Setup

Load Packages

##Install Packages if Needed
if (!require("ggplot2")) install.packages("ggplot2")
if (!require("effectsize")) install.packages("effectsize")
if (!require("emmeans")) install.packages("emmeans")
if (!require("dplyr")) install.packages("dplyr")
if (!require("tidyr")) install.packages("tidyr")
if (!require("Rmisc")) install.packages("Rmisc")
if (!require("ggpubr")) install.packages("ggpubr")
if (!require("cowplot")) install.packages("cowplot")
if (!require("gridGraphics")) install.packages("gridGraphics")
if (!require("tidyr")) install.packages("tidyr")

##Load Packages
library(ggplot2) #Required for plotting
library(effectsize) #Required for eta_squared effect sizes
library(emmeans) #Required for pairwise comparisons
library(dplyr) #Required to seperate columns in dataframe
library(tidyr) #Required for data organization
library(Rmisc) #Required for summarySE for summary statistics
library(ggpubr) #Required for adding pairwise p-values to plots with stat_pvalue_manual 
library(cowplot) #Required for arranging ggplots 
library(gridGraphics) #Required for adding labels to arranged plots
library(tidyr) #Required for reshaping datafrom from a wide to long format.

Note: Run “Graphing Parameters” section from 01_ExperimentalSetup.R file

Load and Organize Data

Note: Full Data with Bleaching Metrics and Color Scores created in 04_Models.R file

#Load Data
FullData<-read.csv("Outputs/FullData.csv", header=TRUE)


#Set factor variables 
FullData$TimeP<-factor(FullData$TimeP, levels=c("W2", "M1", "M4"), ordered=TRUE)
FullData$Site<-factor(FullData$Site, levels=c("KL", "SS"), ordered=TRUE)
FullData$Genotype<-factor(FullData$Genotype, levels=c("AC10", "AC12", "AC8"), ordered=TRUE)
FullData$Treatment<-factor(FullData$Treatment, levels=c("Control", "Heat"), ordered=TRUE)
FullData$Treat<-factor(FullData$Treat, levels=c("C", "H"), ordered=TRUE)
FullData$Seas<-factor(FullData$Seas, levels=c("Summer1", "Summer2", "Winter"), ordered=TRUE)

Percent Retention

Subset Thermal Assay Data by Treatment

##Control
FullData_C<-subset(FullData, Treat=="C")

##Heated
FullData_H<-subset(FullData, Treat=="H")

Calculate Percent Retention

Calculating retention as proportion remaining relative to corresponding control levels (0-1) for each site and genotype at each timepoint.

##Calculate averages for Control Treatment for each Site, Genotype, Timepoint, and Season
names(FullData_C)
 [1] "ID"          "TimeP"       "Site"        "Genotype"    "Treat"       "Treatment"  
 [7] "Seas"        "Set"         "Score_Full"  "Score_TP"    "RandN"       "SA_cm2"     
[13] "Chl_ug.cm2"  "Sym10.6_cm2"
FullData_C.a<-aggregate(FullData_C[,c(9:10, 13:14)], list(FullData_C$Site, FullData_C$Genotype, FullData_C$TimeP, FullData_C$Seas), mean, na.action = na.omit)
names(FullData_C.a)[1:4]<-c("Site", "Genotype", "TimeP", "Seas")
names(FullData_C.a)[5:8]<-paste(names(FullData_C)[c(9:10, 13:14)], "C", sep="_")

##Merge Control Averages with Heated Samples
#Merges by Site, Genotype, Timepoint, and Season
TolData<-merge(FullData_H, FullData_C.a, all.x=TRUE )

##Calculate Proportion Retained for each Bleaching Metric relative to Control
TolData$Score_Full.prop<-round((TolData$Score_Full/TolData$Score_Full_C), 4)
TolData$Score_TP.prop<-round((TolData$Score_TP/TolData$Score_TP_C), 4)
TolData$Chl.prop<-round((TolData$Chl_ug.cm2/TolData$Chl_ug.cm2_C), 4)
TolData$Sym.prop<-round((TolData$Sym10.6_cm2/TolData$Sym10.6_cm2_C), 4)

##Set values >1 to 1
TolData$Score_Full.prop[which(TolData$Score_Full.prop>1)]<-1.0000
TolData$Score_TP.prop[which(TolData$Score_TP.prop>1)]<-1.0000
TolData$Chl.prop[which(TolData$Chl.prop>1)]<-1.0000
TolData$Sym.prop[which(TolData$Sym.prop>1)]<-1.0000

##Create Site and Genotype Variable
TolData$Site.Geno<-paste(TolData$Site, TolData$Genotype, sep="_")

Subset by Timepoint

TolData_W2<-subset(TolData, TimeP=="W2")
TolData_M1<-subset(TolData, TimeP=="M1")
TolData_M4<-subset(TolData, TimeP=="M4")

Thermal Tolerance Chlorophyll

Full Set

Run Model

##Check normality
hist(TolData$Chl.prop)

shapiro.test(TolData$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData$Chl.prop
W = 0.97395, p-value = 0.165
#Normal

##Model as a function of Site and Genotype and Timepoint
Tol_Chl_lm<-lm(Chl.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_lm)); qqline(resid(Tol_Chl_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_lm), resid(Tol_Chl_lm))

Model Results

#Model Results
summary(Tol_Chl_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.127060 -0.031006 -0.004219  0.036829  0.097690 

Coefficients:
                     Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.2100753  0.0065828  31.913  < 2e-16 ***
Site.L             -0.0093229  0.0092942  -1.003 0.320289    
Genotype.L         -0.0980285  0.0111500  -8.792 5.31e-12 ***
Genotype.Q         -0.0467859  0.0116301  -4.023 0.000180 ***
TimeP.L             0.0638187  0.0112994   5.648 6.22e-07 ***
TimeP.Q             0.0464233  0.0115033   4.036 0.000173 ***
Site.L:Genotype.L   0.0003917  0.0157685   0.025 0.980272    
Site.L:Genotype.Q   0.0592529  0.0164183   3.609 0.000673 ***
Site.L:TimeP.L     -0.0528050  0.0159798  -3.304 0.001694 ** 
Site.L:TimeP.Q     -0.0236749  0.0161894  -1.462 0.149435    
Genotype.L:TimeP.L  0.0406686  0.0194339   2.093 0.041093 *  
Genotype.Q:TimeP.L -0.0627603  0.0196595  -3.192 0.002354 ** 
Genotype.L:TimeP.Q  0.0800244  0.0191901   4.170 0.000111 ***
Genotype.Q:TimeP.Q -0.1328570  0.0206170  -6.444 3.28e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05393 on 54 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.8229,    Adjusted R-squared:  0.7803 
F-statistic:  19.3 on 13 and 54 DF,  p-value: 8.612e-16
anova(Tol_Chl_lm)
Analysis of Variance Table

Response: Chl.prop
               Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.001563 0.001563  0.5375  0.466633    
Genotype        2 0.297307 0.148654 51.1117 3.495e-13 ***
TimeP           2 0.132285 0.066142 22.7418 6.845e-08 ***
Site:Genotype   2 0.041114 0.020557  7.0681  0.001877 ** 
Site:TimeP      2 0.038643 0.019322  6.6434  0.002634 ** 
Genotype:TimeP  4 0.218951 0.054738 18.8205 9.691e-10 ***
Residuals      54 0.157054 0.002908                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           | 1.76e-03 | [0.00, 1.00]
Genotype       |     0.34 | [0.16, 1.00]
TimeP          |     0.15 | [0.02, 1.00]
Site:Genotype  |     0.05 | [0.00, 1.00]
Site:TimeP     |     0.04 | [0.00, 1.00]
Genotype:TimeP |     0.25 | [0.06, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_lm.res<-data.frame(anova(Tol_Chl_lm))
Tol_Chl_lm.res$Predictor<-rownames(Tol_Chl_lm.res)
Tol_Chl_lm.res$EtaSq<-c(eta_squared(Tol_Chl_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_lm.res))
Tol_Chl_lm.res<-Tol_Chl_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with main variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Chl Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Chl.prop)

shapiro.test(TolData_W2$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Chl.prop
W = 0.98407, p-value = 0.9671
#Normal

##Model as a function of Site and Genotype
Tol_Chl_W2_lm<-lm(Chl.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_W2_lm)); qqline(resid(Tol_Chl_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_W2_lm), resid(Tol_Chl_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_W2_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + Site:Genotype, data = TolData_W2)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.089900 -0.031587 -0.008183  0.038881  0.103550 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.1842264  0.0119450  15.423 5.03e-11 ***
Site.L             0.0188110  0.0168928   1.114 0.281921    
Genotype.L        -0.0947759  0.0204291  -4.639 0.000273 ***
Genotype.Q        -0.0585870  0.0209464  -2.797 0.012921 *  
Site.L:Genotype.L -0.0002833  0.0288911  -0.010 0.992297    
Site.L:Genotype.Q  0.0366569  0.0296227   1.237 0.233769    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05552 on 16 degrees of freedom
  (1 observation deleted due to missingness)
Multiple R-squared:  0.6758,    Adjusted R-squared:  0.5745 
F-statistic: 6.671 on 5 and 16 DF,  p-value: 0.001551
anova(Tol_Chl_W2_lm)
Analysis of Variance Table

Response: Chl.prop
              Df   Sum Sq  Mean Sq F value   Pr(>F)    
Site           1 0.005580 0.005580  1.8106 0.197195    
Genotype       2 0.092482 0.046241 15.0038 0.000214 ***
Site:Genotype  2 0.004732 0.002366  0.7677 0.480448    
Residuals     16 0.049311 0.003082                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.04 | [0.00, 1.00]
Genotype      | 0.61 | [0.29, 1.00]
Site:Genotype | 0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_W2_lm.res<-data.frame(anova(Tol_Chl_W2_lm))
Tol_Chl_W2_lm.res$Predictor<-rownames(Tol_Chl_W2_lm.res)
Tol_Chl_W2_lm.res$EtaSq<-c(eta_squared(Tol_Chl_W2_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_W2_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_W2_lm.res))
Tol_Chl_W2_lm.res$TimeP<-rep("W2", nrow(Tol_Chl_W2_lm.res))
Tol_Chl_W2_lm.res<-Tol_Chl_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.2033 0.0278 16   0.1445    0.262
 AC12     0.2399 0.0278 16   0.1811    0.299
 AC8      0.0696 0.0278 16   0.0107    0.128

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.2514 0.0278 16   0.1925    0.310
 AC12     0.2242 0.0321 16   0.1563    0.292
 AC8      0.1170 0.0321 16   0.0491    0.185

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12  -0.0366 0.0393 16  -0.933  0.6280
 AC10 - AC8    0.1338 0.0393 16   3.407  0.0095
 AC12 - AC8    0.1704 0.0393 16   4.340  0.0014

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0272 0.0424 16   0.640  0.8003
 AC10 - AC8    0.1343 0.0424 16   3.168  0.0156
 AC12 - AC8    0.1072 0.0453 16   2.364  0.0753

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.2033 0.0278 16   0.1445    0.262
 SS   0.2514 0.0278 16   0.1925    0.310

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.2399 0.0278 16   0.1811    0.299
 SS   0.2242 0.0321 16   0.1563    0.292

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0696 0.0278 16   0.0107    0.128
 SS   0.1170 0.0321 16   0.0491    0.185

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0481 0.0393 16  -1.224  0.2387

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS    0.0157 0.0424 16   0.371  0.7156

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0475 0.0424 16  -1.120  0.2793
##Save p-values

#Genotypes within Sites
Tol_Chl_W2_lm.geno<-data.frame(emmeans(Tol_Chl_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_W2_lm.geno<-Tol_Chl_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_W2_lm.geno$group1<-paste(Tol_Chl_W2_lm.geno$Site, Tol_Chl_W2_lm.geno$group1, sep="_")
Tol_Chl_W2_lm.geno$group2<-paste(Tol_Chl_W2_lm.geno$Site, Tol_Chl_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_W2_lm.site<-data.frame(emmeans(Tol_Chl_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_W2_lm.site<-Tol_Chl_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_W2_lm.site$group1<-paste(Tol_Chl_W2_lm.site$group1, Tol_Chl_W2_lm.site$Genotype, sep="_")
Tol_Chl_W2_lm.site$group2<-paste(Tol_Chl_W2_lm.site$group2, Tol_Chl_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_W2_lm.p<-rbind(Tol_Chl_W2_lm.geno[,c(1:2,4:8)], Tol_Chl_W2_lm.site[,c(1:2,4:8)])
Tol_Chl_W2_lm.p<-Tol_Chl_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_W2_lm.p$Sig<-ifelse(Tol_Chl_W2_lm.p$p<0.001, "***", ifelse(Tol_Chl_W2_lm.p$p<0.01, "**", ifelse(Tol_Chl_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_W2_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_W2_lm.p))
Tol_Chl_W2_lm.p$TimeP<-rep("W2", nrow(Tol_Chl_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_W2_SG<-summarySE(TolData_W2, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_W2_SG.plot<-ggplot(Tol_Chl_W2_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Chlorophyll Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_W2_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE); Tol_Chl_W2_SG.plot

Chl Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Chl.prop)

shapiro.test(TolData_M1$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Chl.prop
W = 0.9306, p-value = 0.1263
#Normal

##Model as a function of Site and Genotype
Tol_Chl_M1_lm<-lm(Chl.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_M1_lm)); qqline(resid(Tol_Chl_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_M1_lm), resid(Tol_Chl_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_M1_lm)

Call:
lm(formula = Chl.prop ~ Site + Genotype + Site:Genotype, data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.107050 -0.034575  0.003479  0.025531  0.088050 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.17217    0.01178  14.619 1.12e-10 ***
Site.L             0.01036    0.01666   0.622   0.5428    
Genotype.L        -0.16337    0.01935  -8.442 2.74e-07 ***
Genotype.Q         0.06169    0.02139   2.883   0.0108 *  
Site.L:Genotype.L  0.03819    0.02737   1.395   0.1820    
Site.L:Genotype.Q  0.05454    0.03026   1.803   0.0903 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05474 on 16 degrees of freedom
Multiple R-squared:  0.8424,    Adjusted R-squared:  0.7932 
F-statistic: 17.11 on 5 and 16 DF,  p-value: 6.411e-06
anova(Tol_Chl_M1_lm)
Analysis of Variance Table

Response: Chl.prop
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.002283 0.002283  0.7619    0.3956    
Genotype       2 0.238424 0.119212 39.7888 6.168e-07 ***
Site:Genotype  2 0.015569 0.007785  2.5982    0.1054    
Residuals     16 0.047938 0.002996                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 7.50e-03 | [0.00, 1.00]
Genotype      |     0.78 | [0.58, 1.00]
Site:Genotype |     0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_M1_lm.res<-data.frame(anova(Tol_Chl_M1_lm))
Tol_Chl_M1_lm.res$Predictor<-rownames(Tol_Chl_M1_lm.res)
Tol_Chl_M1_lm.res$EtaSq<-c(eta_squared(Tol_Chl_M1_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_M1_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_M1_lm.res))
Tol_Chl_M1_lm.res$TimeP<-rep("M1", nrow(Tol_Chl_M1_lm.res))
Tol_Chl_M1_lm.res<-Tol_Chl_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.3089 0.0274 16   0.2509   0.3669
 AC12     0.1460 0.0316 16   0.0790   0.2130
 AC8      0.0397 0.0274 16  -0.0183   0.0977

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.3169 0.0274 16   0.2588   0.3749
 AC12     0.0976 0.0316 16   0.0306   0.1646
 AC8      0.1240 0.0274 16   0.0660   0.1820

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1629 0.0418 16   3.897  0.0035
 AC10 - AC8    0.2692 0.0387 16   6.956  <.0001
 AC12 - AC8    0.1063 0.0418 16   2.543  0.0538

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.2192 0.0418 16   5.244  0.0002
 AC10 - AC8    0.1928 0.0387 16   4.983  0.0004
 AC12 - AC8   -0.0264 0.0418 16  -0.631  0.8056

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.3089 0.0274 16   0.2509   0.3669
 SS   0.3169 0.0274 16   0.2588   0.3749

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.1460 0.0316 16   0.0790   0.2130
 SS   0.0976 0.0316 16   0.0306   0.1646

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0397 0.0274 16  -0.0183   0.0977
 SS   0.1240 0.0274 16   0.0660   0.1820

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00795 0.0387 16  -0.205  0.8398

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.04833 0.0447 16   1.081  0.2955

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.08432 0.0387 16  -2.179  0.0447
##Save p-values

#Genotypes within Sites
Tol_Chl_M1_lm.geno<-data.frame(emmeans(Tol_Chl_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_M1_lm.geno<-Tol_Chl_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M1_lm.geno$group1<-paste(Tol_Chl_M1_lm.geno$Site, Tol_Chl_M1_lm.geno$group1, sep="_")
Tol_Chl_M1_lm.geno$group2<-paste(Tol_Chl_M1_lm.geno$Site, Tol_Chl_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_M1_lm.site<-data.frame(emmeans(Tol_Chl_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_M1_lm.site<-Tol_Chl_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M1_lm.site$group1<-paste(Tol_Chl_M1_lm.site$group1, Tol_Chl_M1_lm.site$Genotype, sep="_")
Tol_Chl_M1_lm.site$group2<-paste(Tol_Chl_M1_lm.site$group2, Tol_Chl_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_M1_lm.p<-rbind(Tol_Chl_M1_lm.geno[,c(1:2,4:8)], Tol_Chl_M1_lm.site[,c(1:2,4:8)])
Tol_Chl_M1_lm.p<-Tol_Chl_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_M1_lm.p$Sig<-ifelse(Tol_Chl_M1_lm.p$p<0.001, "***", ifelse(Tol_Chl_M1_lm.p$p<0.01, "**", ifelse(Tol_Chl_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_M1_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_M1_lm.p))
Tol_Chl_M1_lm.p$TimeP<-rep("M1", nrow(Tol_Chl_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_M1_SG<-summarySE(TolData_M1, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_M1_SG.plot<-ggplot(Tol_Chl_M1_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Chlorophyll Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M1_lm.p,  y.position=0.4, step.increase=0.25, label="Sig", hide.ns=TRUE); Tol_Chl_M1_SG.plot

Chl Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Chl.prop)

shapiro.test(TolData_M4$Chl.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Chl.prop
W = 0.91299, p-value = 0.04096
#Not Normal

##Try log+1 transformation
hist(log(TolData_M4$Chl.prop+1))

shapiro.test(log(TolData_M4$Chl.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData_M4$Chl.prop + 1)
W = 0.93102, p-value = 0.1028
#Normal

##Model as a function of Site and Genotype
##Model with log transformation
Tol_Chl_M4_lm<-lm(log(Chl.prop+1)~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Chl_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_Chl_M4_lm)); qqline(resid(Tol_Chl_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Chl_M4_lm), resid(Tol_Chl_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_Chl_M4_lm)

Call:
lm(formula = log(Chl.prop + 1) ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.062753 -0.025900 -0.004896  0.017009  0.065759 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.23863    0.00807  29.568  < 2e-16 ***
Site.L            -0.04272    0.01141  -3.743  0.00149 ** 
Genotype.L        -0.03027    0.01398  -2.166  0.04400 *  
Genotype.Q        -0.11052    0.01398  -7.907  2.9e-07 ***
Site.L:Genotype.L -0.03189    0.01977  -1.613  0.12415    
Site.L:Genotype.Q  0.05753    0.01977   2.910  0.00934 ** 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03954 on 18 degrees of freedom
Multiple R-squared:  0.8368,    Adjusted R-squared:  0.7915 
F-statistic: 18.46 on 5 and 18 DF,  p-value: 1.598e-06
anova(Tol_Chl_M4_lm)
Analysis of Variance Table

Response: log(Chl.prop + 1)
              Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site           1 0.021901 0.021901 14.0102  0.001489 ** 
Genotype       2 0.105056 0.052528 33.6031 8.379e-07 ***
Site:Genotype  2 0.017304 0.008652  5.5349  0.013381 *  
Residuals     18 0.028137 0.001563                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Chl_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.13 | [0.00, 1.00]
Genotype      | 0.61 | [0.32, 1.00]
Site:Genotype | 0.10 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Chl_M4_lm.res<-data.frame(anova(Tol_Chl_M4_lm))
Tol_Chl_M4_lm.res$Predictor<-rownames(Tol_Chl_M4_lm.res)
Tol_Chl_M4_lm.res$EtaSq<-c(eta_squared(Tol_Chl_M4_lm, partial=FALSE)$Eta2, NA)
Tol_Chl_M4_lm.res$Response<-rep("Chlorophyll", nrow(Tol_Chl_M4_lm.res))
Tol_Chl_M4_lm.res$TimeP<-rep("M4", nrow(Tol_Chl_M4_lm.res))
Tol_Chl_M4_lm.res<-Tol_Chl_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype and Site*Genotype.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Chl_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.213 0.0198 18    0.171    0.254
 AC12      0.392 0.0198 18    0.351    0.434
 AC8       0.202 0.0198 18    0.160    0.243

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.217 0.0198 18    0.176    0.259
 AC12      0.265 0.0198 18    0.224    0.307
 AC8       0.143 0.0198 18    0.101    0.184

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12  -0.1797 0.028 18  -6.428  <.0001
 AC10 - AC8    0.0109 0.028 18   0.391  0.9196
 AC12 - AC8    0.1906 0.028 18   6.819  <.0001

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12  -0.0482 0.028 18  -1.724  0.2237
 AC10 - AC8    0.0747 0.028 18   2.672  0.0393
 AC12 - AC8    0.1229 0.028 18   4.396  0.0010

Note: contrasts are still on the log(mu + 1) scale 
P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Chl_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.213 0.0198 18    0.171    0.254
 SS    0.217 0.0198 18    0.176    0.259

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.392 0.0198 18    0.351    0.434
 SS    0.265 0.0198 18    0.224    0.307

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.202 0.0198 18    0.160    0.243
 SS    0.143 0.0198 18    0.101    0.184

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS  -0.00468 0.028 18  -0.167  0.8688

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS   0.12684 0.028 18   4.537  0.0003

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS   0.05909 0.028 18   2.114  0.0488

Note: contrasts are still on the log(mu + 1) scale 
##Save p-values

#Genotypes within Sites
Tol_Chl_M4_lm.geno<-data.frame(emmeans(Tol_Chl_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_Chl_M4_lm.geno<-Tol_Chl_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M4_lm.geno$group1<-paste(Tol_Chl_M4_lm.geno$Site, Tol_Chl_M4_lm.geno$group1, sep="_")
Tol_Chl_M4_lm.geno$group2<-paste(Tol_Chl_M4_lm.geno$Site, Tol_Chl_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Chl_M4_lm.site<-data.frame(emmeans(Tol_Chl_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_Chl_M4_lm.site<-Tol_Chl_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Chl_M4_lm.site$group1<-paste(Tol_Chl_M4_lm.site$group1, Tol_Chl_M4_lm.site$Genotype, sep="_")
Tol_Chl_M4_lm.site$group2<-paste(Tol_Chl_M4_lm.site$group2, Tol_Chl_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Chl_M4_lm.p<-rbind(Tol_Chl_M4_lm.geno[,c(1:2,4:8)], Tol_Chl_M4_lm.site[,c(1:2,4:8)])
Tol_Chl_M4_lm.p<-Tol_Chl_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Chl_M4_lm.p$Sig<-ifelse(Tol_Chl_M4_lm.p$p<0.001, "***", ifelse(Tol_Chl_M4_lm.p$p<0.01, "**", ifelse(Tol_Chl_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Chl_M4_lm.p$Response<-rep("Chlorophyll", nrow(Tol_Chl_M4_lm.p))
Tol_Chl_M4_lm.p$TimeP<-rep("M4", nrow(Tol_Chl_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Chl_M4_SG<-summarySE(TolData_M4, measurevar="Chl.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Chl_M4_SG.plot<-ggplot(Tol_Chl_M4_SG, aes(x=Site.Geno, y=Chl.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Chl.prop-se, ymax=Chl.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Chlorophyll Retained")+
  ylim(0, 1)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Chl_M4_lm.p,  y.position=0.55, step.increase=0.20, label="Sig", hide.ns=TRUE); Tol_Chl_M4_SG.plot

Thermal Tolerance Symbionts

Full Set

Run Model

##Check normality
hist(TolData$Sym.prop)

shapiro.test(TolData$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData$Sym.prop
W = 0.92235, p-value = 0.0003707
#Not Normal

##Try log+1 transformation
hist(log(TolData$Sym.prop+1))

shapiro.test(log(TolData$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData$Sym.prop + 1)
W = 0.92164, p-value = 0.000345
#Not normal 

##Try square transformation
hist((TolData$Sym.prop)^2)

shapiro.test((TolData$Sym.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Sym.prop)^2
W = 0.87147, p-value = 3.933e-06
#Not normal 

##Try cubed transformation
hist((TolData$Sym.prop)^3)

shapiro.test((TolData$Sym.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Sym.prop)^3
W = 0.80697, p-value = 4.342e-08
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_Sym_lm<-lm(Sym.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_lm)); qqline(resid(Tol_Sym_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_lm), resid(Tol_Sym_lm))

Model Results

#Model Results
summary(Tol_Sym_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.37464 -0.08630 -0.00192  0.08972  0.35883 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.544513   0.018576  29.313  < 2e-16 ***
Site.L             -0.001834   0.026197  -0.070 0.944443    
Genotype.L         -0.373179   0.031737 -11.758  < 2e-16 ***
Genotype.Q          0.028101   0.032605   0.862 0.392497    
TimeP.L             0.133503   0.031737   4.206 9.64e-05 ***
TimeP.Q             0.190344   0.032605   5.838 2.94e-07 ***
Site.L:Genotype.L  -0.060389   0.044883  -1.345 0.183999    
Site.L:Genotype.Q   0.074992   0.045930   1.633 0.108240    
Site.L:TimeP.L     -0.159707   0.044883  -3.558 0.000778 ***
Site.L:TimeP.Q     -0.027928   0.045930  -0.608 0.545653    
Genotype.L:TimeP.L  0.085371   0.055316   1.543 0.128489    
Genotype.Q:TimeP.L -0.084924   0.054623  -1.555 0.125749    
Genotype.L:TimeP.Q  0.065986   0.054623   1.208 0.232204    
Genotype.Q:TimeP.Q -0.205029   0.058264  -3.519 0.000878 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1535 on 55 degrees of freedom
Multiple R-squared:  0.8036,    Adjusted R-squared:  0.7572 
F-statistic: 17.31 on 13 and 55 DF,  p-value: 6.022e-15
anova(Tol_Sym_lm)
Analysis of Variance Table

Response: Sym.prop
               Df Sum Sq Mean Sq F value    Pr(>F)    
Site            1 0.0007 0.00068  0.0289  0.865708    
Genotype        2 3.2796 1.63981 69.5880 8.602e-16 ***
TimeP           2 1.1556 0.57780 24.5197 2.438e-08 ***
Site:Genotype   2 0.1111 0.05557  2.3581  0.104096    
Site:TimeP      2 0.3138 0.15688  6.6576  0.002575 ** 
Genotype:TimeP  4 0.4428 0.11069  4.6974  0.002474 ** 
Residuals      55 1.2961 0.02356                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           | 1.03e-04 | [0.00, 1.00]
Genotype       |     0.50 | [0.33, 1.00]
TimeP          |     0.18 | [0.04, 1.00]
Site:Genotype  |     0.02 | [0.00, 1.00]
Site:TimeP     |     0.05 | [0.00, 1.00]
Genotype:TimeP |     0.07 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_lm.res<-data.frame(anova(Tol_Sym_lm))
Tol_Sym_lm.res$Predictor<-rownames(Tol_Sym_lm.res)
Tol_Sym_lm.res$EtaSq<-c(eta_squared(Tol_Sym_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_lm.res))
Tol_Sym_lm.res<-Tol_Sym_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with main variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Sym Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Sym.prop)

shapiro.test(TolData_W2$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Sym.prop
W = 0.93605, p-value = 0.1477
#Normal

##Model as a function of Site and Genotype
Tol_Sym_W2_lm<-lm(Sym.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_W2_lm)); qqline(resid(Tol_Sym_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_W2_lm), resid(Tol_Sym_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_W2_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + Site:Genotype, data = TolData_W2)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.26060 -0.11145  0.00000  0.08525  0.28580 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.5237625  0.0325072  16.112 9.90e-12 ***
Site.L             0.0939568  0.0459722   2.044   0.0568 .  
Genotype.L        -0.4152131  0.0570402  -7.279 1.29e-06 ***
Genotype.Q        -0.0005205  0.0555584  -0.009   0.9926    
Site.L:Genotype.L -0.2061000  0.0806671  -2.555   0.0205 *  
Site.L:Genotype.Q  0.0462891  0.0785715   0.589   0.5635    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.155 on 17 degrees of freedom
Multiple R-squared:  0.7924,    Adjusted R-squared:  0.7313 
F-statistic: 12.98 on 5 and 17 DF,  p-value: 2.647e-05
anova(Tol_Sym_W2_lm)
Analysis of Variance Table

Response: Sym.prop
              Df  Sum Sq Mean Sq F value    Pr(>F)    
Site           1 0.16148 0.16148  6.7208   0.01897 *  
Genotype       2 1.22843 0.61421 25.5640 7.508e-06 ***
Site:Genotype  2 0.16883 0.08441  3.5133   0.05283 .  
Residuals     17 0.40845 0.02403                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.08 | [0.00, 1.00]
Genotype      | 0.62 | [0.33, 1.00]
Site:Genotype | 0.09 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_W2_lm.res<-data.frame(anova(Tol_Sym_W2_lm))
Tol_Sym_W2_lm.res$Predictor<-rownames(Tol_Sym_W2_lm.res)
Tol_Sym_W2_lm.res$EtaSq<-c(eta_squared(Tol_Sym_W2_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_W2_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_W2_lm.res))
Tol_Sym_W2_lm.res$TimeP<-rep("W2", nrow(Tol_Sym_W2_lm.res))
Tol_Sym_W2_lm.res<-Tol_Sym_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Marginal effect (p<0.1) of Site * Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.634 0.0775 17   0.4708    0.798
 AC12      0.484 0.0775 17   0.3210    0.648
 AC8       0.253 0.0775 17   0.0897    0.417

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      1.000 0.0775 17   0.8365    1.164
 AC12      0.564 0.0775 17   0.4004    0.727
 AC8       0.207 0.0895 17   0.0179    0.396

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.150 0.110 17   1.367  0.3795
 AC10 - AC8     0.381 0.110 17   3.477  0.0077
 AC12 - AC8     0.231 0.110 17   2.110  0.1174

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.436 0.110 17   3.979  0.0026
 AC10 - AC8     0.793 0.118 17   6.701  <.0001
 AC12 - AC8     0.357 0.118 17   3.017  0.0201

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.634 0.0775 17   0.4708    0.798
 SS    1.000 0.0775 17   0.8365    1.164

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.484 0.0775 17   0.3210    0.648
 SS    0.564 0.0775 17   0.4004    0.727

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.253 0.0775 17   0.0897    0.417
 SS    0.207 0.0895 17   0.0179    0.396

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.3657 0.110 17  -3.337  0.0039

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.0794 0.110 17  -0.725  0.4785

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.0465 0.118 17   0.393  0.6994
##Save p-values

#Genotypes within Sites
Tol_Sym_W2_lm.geno<-data.frame(emmeans(Tol_Sym_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_W2_lm.geno<-Tol_Sym_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_W2_lm.geno$group1<-paste(Tol_Sym_W2_lm.geno$Site, Tol_Sym_W2_lm.geno$group1, sep="_")
Tol_Sym_W2_lm.geno$group2<-paste(Tol_Sym_W2_lm.geno$Site, Tol_Sym_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_W2_lm.site<-data.frame(emmeans(Tol_Sym_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_W2_lm.site<-Tol_Sym_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_W2_lm.site$group1<-paste(Tol_Sym_W2_lm.site$group1, Tol_Sym_W2_lm.site$Genotype, sep="_")
Tol_Sym_W2_lm.site$group2<-paste(Tol_Sym_W2_lm.site$group2, Tol_Sym_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_W2_lm.p<-rbind(Tol_Sym_W2_lm.geno[,c(1:2,4:8)], Tol_Sym_W2_lm.site[,c(1:2,4:8)])
Tol_Sym_W2_lm.p<-Tol_Sym_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_W2_lm.p$Sig<-ifelse(Tol_Sym_W2_lm.p$p<0.001, "***", ifelse(Tol_Sym_W2_lm.p$p<0.01, "**", ifelse(Tol_Sym_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_W2_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_W2_lm.p))
Tol_Sym_W2_lm.p$TimeP<-rep("W2", nrow(Tol_Sym_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_W2_SG<-summarySE(TolData_W2, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_W2_SG.plot<-ggplot(Tol_Sym_W2_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Symbionts Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_W2_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_W2_SG.plot

Sym Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Sym.prop)

shapiro.test(TolData_M1$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Sym.prop
W = 0.85748, p-value = 0.004618
#Not normal

##Try log+1 transformation
hist(log(TolData_M1$Sym.prop+1))

shapiro.test(log(TolData_M1$Sym.prop+1))

    Shapiro-Wilk normality test

data:  log(TolData_M1$Sym.prop + 1)
W = 0.87335, p-value = 0.009041
#Not normal but improved

##Model as a function of Site and Genotype
##Model with log transformation
Tol_Sym_M1_lm<-lm(log(Sym.prop+1)~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_M1_lm)); qqline(resid(Tol_Sym_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_M1_lm), resid(Tol_Sym_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_M1_lm)

Call:
lm(formula = log(Sym.prop + 1) ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.098079 -0.055799 -0.004888  0.043331  0.151113 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.307716   0.016556  18.587 2.95e-12 ***
Site.L             0.027767   0.023413   1.186 0.252954    
Genotype.L        -0.295494   0.027204 -10.862 8.59e-09 ***
Genotype.Q         0.129387   0.030075   4.302 0.000548 ***
Site.L:Genotype.L  0.080682   0.038472   2.097 0.052224 .  
Site.L:Genotype.Q -0.005572   0.042532  -0.131 0.897412    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.07694 on 16 degrees of freedom
Multiple R-squared:  0.8989,    Adjusted R-squared:  0.8673 
F-statistic: 28.46 on 5 and 16 DF,  p-value: 2e-07
anova(Tol_Sym_M1_lm)
Analysis of Variance Table

Response: log(Sym.prop + 1)
              Df  Sum Sq Mean Sq F value    Pr(>F)    
Site           1 0.00823 0.00823  1.3902    0.2556    
Genotype       2 0.80811 0.40406 68.2486 1.468e-08 ***
Site:Genotype  2 0.02614 0.01307  2.2076    0.1423    
Residuals     16 0.09473 0.00592                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 8.78e-03 | [0.00, 1.00]
Genotype      |     0.86 | [0.73, 1.00]
Site:Genotype |     0.03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_M1_lm.res<-data.frame(anova(Tol_Sym_M1_lm))
Tol_Sym_M1_lm.res$Predictor<-rownames(Tol_Sym_M1_lm.res)
Tol_Sym_M1_lm.res$EtaSq<-c(eta_squared(Tol_Sym_M1_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_M1_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_M1_lm.res))
Tol_Sym_M1_lm.res$TimeP<-rep("M1", nrow(Tol_Sym_M1_lm.res))
Tol_Sym_M1_lm.res<-Tol_Sym_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.5918 0.0385 16   0.5102    0.673
 AC12     0.1792 0.0444 16   0.0850    0.273
 AC8      0.0932 0.0385 16   0.0117    0.175

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10     0.5472 0.0385 16   0.4656    0.629
 AC12     0.2249 0.0444 16   0.1307    0.319
 AC8      0.2100 0.0385 16   0.1284    0.292

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12    0.413 0.0588 16   7.021  <.0001
 AC10 - AC8     0.499 0.0544 16   9.164  <.0001
 AC12 - AC8     0.086 0.0588 16   1.463  0.3339

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12    0.322 0.0588 16   5.483  0.0001
 AC10 - AC8     0.337 0.0544 16   6.198  <.0001
 AC12 - AC8     0.015 0.0588 16   0.255  0.9650

Note: contrasts are still on the log(mu + 1) scale 
P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL   0.5918 0.0385 16   0.5102    0.673
 SS   0.5472 0.0385 16   0.4656    0.629

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL   0.1792 0.0444 16   0.0850    0.273
 SS   0.2249 0.0444 16   0.1307    0.319

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL   0.0932 0.0385 16   0.0117    0.175
 SS   0.2100 0.0385 16   0.1284    0.292

Results are given on the log(mu + 1) (not the response) scale. 
Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS    0.0446 0.0544 16   0.820  0.4241

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0457 0.0628 16  -0.727  0.4775

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.1167 0.0544 16  -2.146  0.0476

Note: contrasts are still on the log(mu + 1) scale 
##Save p-values

#Genotypes within Sites
Tol_Sym_M1_lm.geno<-data.frame(emmeans(Tol_Sym_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_M1_lm.geno<-Tol_Sym_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M1_lm.geno$group1<-paste(Tol_Sym_M1_lm.geno$Site, Tol_Sym_M1_lm.geno$group1, sep="_")
Tol_Sym_M1_lm.geno$group2<-paste(Tol_Sym_M1_lm.geno$Site, Tol_Sym_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_M1_lm.site<-data.frame(emmeans(Tol_Sym_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_M1_lm.site<-Tol_Sym_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M1_lm.site$group1<-paste(Tol_Sym_M1_lm.site$group1, Tol_Sym_M1_lm.site$Genotype, sep="_")
Tol_Sym_M1_lm.site$group2<-paste(Tol_Sym_M1_lm.site$group2, Tol_Sym_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_M1_lm.p<-rbind(Tol_Sym_M1_lm.geno[,c(1:2,4:8)], Tol_Sym_M1_lm.site[,c(1:2,4:8)])
Tol_Sym_M1_lm.p<-Tol_Sym_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_M1_lm.p$Sig<-ifelse(Tol_Sym_M1_lm.p$p<0.001, "***", ifelse(Tol_Sym_M1_lm.p$p<0.01, "**", ifelse(Tol_Sym_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_M1_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_M1_lm.p))
Tol_Sym_M1_lm.p$TimeP<-rep("M1", nrow(Tol_Sym_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_M1_SG<-summarySE(TolData_M1, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_M1_SG.plot<-ggplot(Tol_Sym_M1_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Symbionts Retained")+
 ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M1_lm.p,  y.position=0.95, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_M1_SG.plot

Sym Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Sym.prop)

shapiro.test(TolData_M4$Sym.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Sym.prop
W = 0.88557, p-value = 0.01078
#Not Normal

##Try square transformation
hist((TolData_M4$Sym.prop)^2)

shapiro.test((TolData_M4$Sym.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Sym.prop)^2
W = 0.87973, p-value = 0.008208
#Not Normal

##Try cubed transformation
hist((TolData_M4$Sym.prop)^3)

shapiro.test((TolData_M4$Sym.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Sym.prop)^3
W = 0.8488, p-value = 0.002077
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_Sym_M4_lm<-lm(Sym.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_Sym_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_Sym_M4_lm)); qqline(resid(Tol_Sym_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_Sym_M4_lm), resid(Tol_Sym_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_Sym_M4_lm)

Call:
lm(formula = Sym.prop ~ Site + Genotype + Site:Genotype, data = TolData_M4)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.31820 -0.08804  0.00000  0.08618  0.29740 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.71662    0.03157  22.702 1.07e-14 ***
Site.L            -0.12617    0.04464  -2.826   0.0112 *  
Genotype.L        -0.28587    0.05467  -5.229 5.67e-05 ***
Genotype.Q        -0.11565    0.05467  -2.115   0.0486 *  
Site.L:Genotype.L -0.09494    0.07732  -1.228   0.2353    
Site.L:Genotype.Q  0.17275    0.07732   2.234   0.0384 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.1546 on 18 degrees of freedom
Multiple R-squared:  0.7201,    Adjusted R-squared:  0.6423 
F-statistic:  9.26 on 5 and 18 DF,  p-value: 0.0001686
anova(Tol_Sym_M4_lm)
Analysis of Variance Table

Response: Sym.prop
              Df  Sum Sq Mean Sq F value   Pr(>F)    
Site           1 0.19101 0.19101  7.9874 0.011190 *  
Genotype       2 0.76080 0.38040 15.9068 0.000105 ***
Site:Genotype  2 0.15542 0.07771  3.2496 0.062386 .  
Residuals     18 0.43046 0.02391                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_Sym_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.12 | [0.00, 1.00]
Genotype      | 0.49 | [0.18, 1.00]
Site:Genotype | 0.10 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_Sym_M4_lm.res<-data.frame(anova(Tol_Sym_M4_lm))
Tol_Sym_M4_lm.res$Predictor<-rownames(Tol_Sym_M4_lm.res)
Tol_Sym_M4_lm.res$EtaSq<-c(eta_squared(Tol_Sym_M4_lm, partial=FALSE)$Eta2, NA)
Tol_Sym_M4_lm.res$Response<-rep("Symbionts", nrow(Tol_Sym_M4_lm.res))
Tol_Sym_M4_lm.res$TimeP<-rep("M4", nrow(Tol_Sym_M4_lm.res))
Tol_Sym_M4_lm.res<-Tol_Sym_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Marginal effect (p<0.1) of Site * Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_Sym_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.863 0.0773 18    0.701    1.026
 AC12      1.000 0.0773 18    0.838    1.162
 AC8       0.554 0.0773 18    0.392    0.717

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.880 0.0773 18    0.717    1.042
 AC12      0.622 0.0773 18    0.460    0.785
 AC8       0.380 0.0773 18    0.218    0.543

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12   -0.137 0.109 18  -1.249  0.4409
 AC10 - AC8     0.309 0.109 18   2.829  0.0285
 AC12 - AC8     0.446 0.109 18   4.078  0.0019

Site = SS:
 contrast    estimate    SE df t.ratio p.value
 AC10 - AC12    0.258 0.109 18   2.356  0.0734
 AC10 - AC8     0.499 0.109 18   4.565  0.0007
 AC12 - AC8     0.242 0.109 18   2.210  0.0965

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_Sym_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.863 0.0773 18    0.701    1.026
 SS    0.880 0.0773 18    0.717    1.042

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    1.000 0.0773 18    0.838    1.162
 SS    0.622 0.0773 18    0.460    0.785

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.554 0.0773 18    0.392    0.717
 SS    0.380 0.0773 18    0.218    0.543

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate    SE df t.ratio p.value
 KL - SS   -0.0163 0.109 18  -0.149  0.8835

Genotype = AC12:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.3779 0.109 18   3.456  0.0028

Genotype = AC8:
 contrast estimate    SE df t.ratio p.value
 KL - SS    0.1736 0.109 18   1.588  0.1297
##Save p-values

#Genotypes within Sites
Tol_Sym_M4_lm.geno<-data.frame(emmeans(Tol_Sym_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_Sym_M4_lm.geno<-Tol_Sym_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M4_lm.geno$group1<-paste(Tol_Sym_M4_lm.geno$Site, Tol_Sym_M4_lm.geno$group1, sep="_")
Tol_Sym_M4_lm.geno$group2<-paste(Tol_Sym_M4_lm.geno$Site, Tol_Sym_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_Sym_M4_lm.site<-data.frame(emmeans(Tol_Sym_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_Sym_M4_lm.site<-Tol_Sym_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_Sym_M4_lm.site$group1<-paste(Tol_Sym_M4_lm.site$group1, Tol_Sym_M4_lm.site$Genotype, sep="_")
Tol_Sym_M4_lm.site$group2<-paste(Tol_Sym_M4_lm.site$group2, Tol_Sym_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_Sym_M4_lm.p<-rbind(Tol_Sym_M4_lm.geno[,c(1:2,4:8)], Tol_Sym_M4_lm.site[,c(1:2,4:8)])
Tol_Sym_M4_lm.p<-Tol_Sym_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_Sym_M4_lm.p$Sig<-ifelse(Tol_Sym_M4_lm.p$p<0.001, "***", ifelse(Tol_Sym_M4_lm.p$p<0.01, "**", ifelse(Tol_Sym_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_Sym_M4_lm.p$Response<-rep("Symbionts", nrow(Tol_Sym_M4_lm.p))
Tol_Sym_M4_lm.p$TimeP<-rep("M4", nrow(Tol_Sym_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_Sym_M4_SG<-summarySE(TolData_M4, measurevar="Sym.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_Sym_M4_SG.plot<-ggplot(Tol_Sym_M4_SG, aes(x=Site.Geno, y=Sym.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Sym.prop-se, ymax=Sym.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Symbionts Retained")+
  ylim(0, 1.5)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_Sym_M4_lm.p,  y.position=1.1, step.increase=0.15, label="Sig", hide.ns=TRUE); Tol_Sym_M4_SG.plot

Thermal Tolerance Color Full Set

Full Set

Run Model

##Check normality
hist(TolData$Score_Full.prop)

shapiro.test(TolData$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData$Score_Full.prop
W = 0.93829, p-value = 0.002023
#Not Normal

##Try square transformation
hist((TolData$Score_Full.prop)^2)

shapiro.test((TolData$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Score_Full.prop)^2
W = 0.95035, p-value = 0.008158
#Not normal 

##Try cubed transformation
hist((TolData$Score_Full.prop)^3)

shapiro.test((TolData$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Score_Full.prop)^3
W = 0.95927, p-value = 0.02433
#Not normal 


##Model as a function of Site and Genotype and Timepoint
##Model with no transformation and check residuals
Tol_ScoreF_lm<-lm(Score_Full.prop~Site+Genotype+TimeP+ Site:Genotype + Site:TimeP + Genotype:TimeP, data=TolData)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_lm)); qqline(resid(Tol_ScoreF_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_lm), resid(Tol_ScoreF_lm))

Model Results

#Model Results
summary(Tol_ScoreF_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.110993 -0.016292  0.006243  0.019125  0.105407 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.915091   0.004407 207.631  < 2e-16 ***
Site.L              0.010360   0.006215   1.667 0.101242    
Genotype.L         -0.066874   0.007530  -8.881 3.28e-12 ***
Genotype.Q          0.012290   0.007736   1.589 0.117866    
TimeP.L             0.030163   0.007530   4.006 0.000187 ***
TimeP.Q             0.035927   0.007736   4.644 2.17e-05 ***
Site.L:Genotype.L   0.008168   0.010649   0.767 0.446384    
Site.L:Genotype.Q   0.016902   0.010898   1.551 0.126651    
Site.L:TimeP.L     -0.014751   0.010649  -1.385 0.171595    
Site.L:TimeP.Q     -0.004576   0.010898  -0.420 0.676193    
Genotype.L:TimeP.L  0.014217   0.013125   1.083 0.283412    
Genotype.Q:TimeP.L  0.015151   0.012960   1.169 0.247420    
Genotype.L:TimeP.Q  0.006442   0.012960   0.497 0.621134    
Genotype.Q:TimeP.Q -0.048959   0.013824  -3.542 0.000819 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03642 on 55 degrees of freedom
Multiple R-squared:  0.717, Adjusted R-squared:  0.6501 
F-statistic: 10.72 on 13 and 55 DF,  p-value: 7.67e-11
anova(Tol_ScoreF_lm)
Analysis of Variance Table

Response: Score_Full.prop
               Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.004778 0.004778  3.6019  0.062967 .  
Genotype        2 0.105770 0.052885 39.8672 1.992e-11 ***
TimeP           2 0.046815 0.023407 17.6455 1.202e-06 ***
Site:Genotype   2 0.004264 0.002132  1.6071  0.209738    
Site:TimeP      2 0.003044 0.001522  1.1474  0.324936    
Genotype:TimeP  4 0.020161 0.005040  3.7996  0.008476 ** 
Residuals      55 0.072959 0.001327                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      | Eta2 |       95% CI
------------------------------------
Site           | 0.02 | [0.00, 1.00]
Genotype       | 0.41 | [0.24, 1.00]
TimeP          | 0.18 | [0.04, 1.00]
Site:Genotype  | 0.02 | [0.00, 1.00]
Site:TimeP     | 0.01 | [0.00, 1.00]
Genotype:TimeP | 0.08 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_lm.res<-data.frame(anova(Tol_ScoreF_lm))
Tol_ScoreF_lm.res$Predictor<-rownames(Tol_ScoreF_lm.res)
Tol_ScoreF_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_lm.res))
Tol_ScoreF_lm.res<-Tol_ScoreF_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with Genotype. Will analyze each Timepoint individually.

Color Score Full Set Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Score_Full.prop)

shapiro.test(TolData_W2$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Score_Full.prop
W = 0.9067, p-value = 0.03483
#Not normal

##Try square transformation
hist((TolData_W2$Score_Full.prop)^2)

shapiro.test((TolData_W2$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_W2$Score_Full.prop)^2
W = 0.91053, p-value = 0.04192
#Not normal

##Try cubed transformation
hist((TolData_W2$Score_Full.prop)^3)

shapiro.test((TolData_W2$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_W2$Score_Full.prop)^3
W = 0.91348, p-value = 0.04837
#Not normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreF_W2_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_W2_lm)); qqline(resid(Tol_ScoreF_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_W2_lm), resid(Tol_ScoreF_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_W2_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_W2)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.073750 -0.015096  0.002375  0.016863  0.047825 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.908519   0.007346 123.672  < 2e-16 ***
Site.L             0.019049   0.010389   1.834   0.0843 .  
Genotype.L        -0.074108   0.012890  -5.749 2.36e-05 ***
Genotype.Q        -0.018301   0.012555  -1.458   0.1632    
Site.L:Genotype.L  0.003346   0.018230   0.184   0.8565    
Site.L:Genotype.Q  0.031449   0.017756   1.771   0.0945 .  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03503 on 17 degrees of freedom
Multiple R-squared:   0.72, Adjusted R-squared:  0.6377 
F-statistic: 8.744 on 5 and 17 DF,  p-value: 0.0002968
anova(Tol_ScoreF_W2_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df   Sum Sq   Mean Sq F value    Pr(>F)    
Site           1 0.005660 0.0056602  4.6129   0.04644 *  
Genotype       2 0.044122 0.0220608 17.9790 6.388e-05 ***
Site:Genotype  2 0.003862 0.0019311  1.5738   0.23601    
Residuals     17 0.020859 0.0012270                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.08 | [0.00, 1.00]
Genotype      | 0.59 | [0.28, 1.00]
Site:Genotype | 0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_W2_lm.res<-data.frame(anova(Tol_ScoreF_W2_lm))
Tol_ScoreF_W2_lm.res$Predictor<-rownames(Tol_ScoreF_W2_lm.res)
Tol_ScoreF_W2_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_W2_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_W2_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_W2_lm.res))
Tol_ScoreF_W2_lm.res$TimeP<-rep("W2", nrow(Tol_ScoreF_W2_lm.res))
Tol_ScoreF_W2_lm.res<-Tol_ScoreF_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.933 0.0175 17    0.896    0.970
 AC12      0.928 0.0175 17    0.891    0.965
 AC8       0.824 0.0175 17    0.787    0.861

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.974 0.0175 17    0.937    1.011
 AC12      0.919 0.0175 17    0.882    0.956
 AC8       0.873 0.0202 17    0.830    0.916

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12  0.00443 0.0248 17   0.179  0.9826
 AC10 - AC8   0.10815 0.0248 17   4.366  0.0012
 AC12 - AC8   0.10372 0.0248 17   4.188  0.0017

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12  0.05555 0.0248 17   2.243  0.0923
 AC10 - AC8   0.10146 0.0268 17   3.792  0.0039
 AC12 - AC8   0.04591 0.0268 17   1.716  0.2281

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.933 0.0175 17    0.896    0.970
 SS    0.974 0.0175 17    0.937    1.011

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.928 0.0175 17    0.891    0.965
 SS    0.919 0.0175 17    0.882    0.956

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.824 0.0175 17    0.787    0.861
 SS    0.873 0.0202 17    0.830    0.916

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.04175 0.0248 17  -1.686  0.1101

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.00937 0.0248 17   0.378  0.7097

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.04844 0.0268 17  -1.811  0.0879
##Save p-values

#Genotypes within Sites
Tol_ScoreF_W2_lm.geno<-data.frame(emmeans(Tol_ScoreF_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_W2_lm.geno<-Tol_ScoreF_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_W2_lm.geno$group1<-paste(Tol_ScoreF_W2_lm.geno$Site, Tol_ScoreF_W2_lm.geno$group1, sep="_")
Tol_ScoreF_W2_lm.geno$group2<-paste(Tol_ScoreF_W2_lm.geno$Site, Tol_ScoreF_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_W2_lm.site<-data.frame(emmeans(Tol_ScoreF_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_W2_lm.site<-Tol_ScoreF_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_W2_lm.site$group1<-paste(Tol_ScoreF_W2_lm.site$group1, Tol_ScoreF_W2_lm.site$Genotype, sep="_")
Tol_ScoreF_W2_lm.site$group2<-paste(Tol_ScoreF_W2_lm.site$group2, Tol_ScoreF_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_W2_lm.p<-rbind(Tol_ScoreF_W2_lm.geno[,c(1:2,4:8)], Tol_ScoreF_W2_lm.site[,c(1:2,4:8)])
Tol_ScoreF_W2_lm.p<-Tol_ScoreF_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_W2_lm.p$Sig<-ifelse(Tol_ScoreF_W2_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_W2_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_W2_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_W2_lm.p))
Tol_ScoreF_W2_lm.p$TimeP<-rep("W2", nrow(Tol_ScoreF_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_W2_SG<-summarySE(TolData_W2, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_W2_SG.plot<-ggplot(Tol_ScoreF_W2_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Color Retained (Full)")+
  ylim(0.6, 1.2)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_W2_lm.p,  y.position=1, step.increase=0.3, label="Sig", hide.ns=TRUE); Tol_ScoreF_W2_SG.plot

Color Score Full Set Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Score_Full.prop)

shapiro.test(TolData_M1$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Score_Full.prop
W = 0.9299, p-value = 0.1221
#Normal

##Model as a function of Site and Genotype
Tol_ScoreF_M1_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_M1_lm)); qqline(resid(Tol_ScoreF_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_M1_lm), resid(Tol_ScoreF_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_M1_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.10493 -0.01089  0.00435  0.01777  0.11147 

Coefficients:
                  Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.88576    0.01035  85.561  < 2e-16 ***
Site.L             0.01338    0.01464   0.914 0.374264    
Genotype.L        -0.07213    0.01701  -4.240 0.000623 ***
Genotype.Q         0.05226    0.01881   2.779 0.013406 *  
Site.L:Genotype.L  0.02579    0.02406   1.072 0.299648    
Site.L:Genotype.Q  0.02652    0.02660   0.997 0.333497    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.04811 on 16 degrees of freedom
Multiple R-squared:  0.6442,    Adjusted R-squared:  0.533 
F-statistic: 5.794 on 5 and 16 DF,  p-value: 0.003073
anova(Tol_ScoreF_M1_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df   Sum Sq   Mean Sq F value    Pr(>F)    
Site           1 0.002592 0.0025921  1.1197 0.3056920    
Genotype       2 0.059505 0.0297527 12.8527 0.0004693 ***
Site:Genotype  2 0.004962 0.0024810  1.0718 0.3657507    
Residuals     16 0.037038 0.0023149                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.02 | [0.00, 1.00]
Genotype      | 0.57 | [0.24, 1.00]
Site:Genotype | 0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_M1_lm.res<-data.frame(anova(Tol_ScoreF_M1_lm))
Tol_ScoreF_M1_lm.res$Predictor<-rownames(Tol_ScoreF_M1_lm.res)
Tol_ScoreF_M1_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_M1_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_M1_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M1_lm.res))
Tol_ScoreF_M1_lm.res$TimeP<-rep("M1", nrow(Tol_ScoreF_M1_lm.res))
Tol_ScoreF_M1_lm.res<-Tol_ScoreF_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.954 0.0241 16    0.903    1.005
 AC12      0.849 0.0278 16    0.790    0.908
 AC8       0.826 0.0241 16    0.775    0.877

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.962 0.0241 16    0.911    1.013
 AC12      0.837 0.0278 16    0.778    0.896
 AC8       0.886 0.0241 16    0.835    0.937

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1049 0.0367 16   2.856  0.0292
 AC10 - AC8    0.1278 0.0340 16   3.756  0.0046
 AC12 - AC8    0.0229 0.0367 16   0.622  0.8103

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1251 0.0367 16   3.404  0.0096
 AC10 - AC8    0.0762 0.0340 16   2.241  0.0945
 AC12 - AC8   -0.0489 0.0367 16  -1.330  0.3998

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.954 0.0241 16    0.903    1.005
 SS    0.962 0.0241 16    0.911    1.013

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.849 0.0278 16    0.790    0.908
 SS    0.837 0.0278 16    0.778    0.896

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.826 0.0241 16    0.775    0.877
 SS    0.886 0.0241 16    0.835    0.937

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00845 0.0340 16  -0.248  0.8070

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.01170 0.0393 16   0.298  0.7697

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.06003 0.0340 16  -1.764  0.0968
##Save p-values

#Genotypes within Sites
Tol_ScoreF_M1_lm.geno<-data.frame(emmeans(Tol_ScoreF_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_M1_lm.geno<-Tol_ScoreF_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M1_lm.geno$group1<-paste(Tol_ScoreF_M1_lm.geno$Site, Tol_ScoreF_M1_lm.geno$group1, sep="_")
Tol_ScoreF_M1_lm.geno$group2<-paste(Tol_ScoreF_M1_lm.geno$Site, Tol_ScoreF_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_M1_lm.site<-data.frame(emmeans(Tol_ScoreF_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_M1_lm.site<-Tol_ScoreF_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M1_lm.site$group1<-paste(Tol_ScoreF_M1_lm.site$group1, Tol_ScoreF_M1_lm.site$Genotype, sep="_")
Tol_ScoreF_M1_lm.site$group2<-paste(Tol_ScoreF_M1_lm.site$group2, Tol_ScoreF_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_M1_lm.p<-rbind(Tol_ScoreF_M1_lm.geno[,c(1:2,4:8)], Tol_ScoreF_M1_lm.site[,c(1:2,4:8)])
Tol_ScoreF_M1_lm.p<-Tol_ScoreF_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_M1_lm.p$Sig<-ifelse(Tol_ScoreF_M1_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_M1_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_M1_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M1_lm.p))
Tol_ScoreF_M1_lm.p$TimeP<-rep("M1", nrow(Tol_ScoreF_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_M1_SG<-summarySE(TolData_M1, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_M1_SG.plot<-ggplot(Tol_ScoreF_M1_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Color Retained (Full)")+
  ylim(0.6, 1.2)+  
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M1_lm.p,  y.position=1, step.increase=0.3, label="Sig", hide.ns=TRUE); Tol_ScoreF_M1_SG.plot

Color Score Full Set Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Score_Full.prop)

shapiro.test(TolData_M4$Score_Full.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Score_Full.prop
W = 0.89096, p-value = 0.01391
#Not Normal

##Try square transformation
hist((TolData_M4$Score_Full.prop)^2)

shapiro.test((TolData_M4$Score_Full.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_Full.prop)^2
W = 0.88924, p-value = 0.01282
#Not Normal

##Try cubed transformation
hist((TolData_M4$Score_Full.prop)^3)

shapiro.test((TolData_M4$Score_Full.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData_M4$Score_Full.prop)^3
W = 0.88739, p-value = 0.01175
#Not Normal

##Model as a function of Site and Genotype
##Model with no transformation and check residuals
Tol_ScoreF_M4_lm<-lm(Score_Full.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreF_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreF_M4_lm)); qqline(resid(Tol_ScoreF_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreF_M4_lm), resid(Tol_ScoreF_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreF_M4_lm)

Call:
lm(formula = Score_Full.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.058700 -0.006500 -0.000900  0.008625  0.047300 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.951088   0.004804 197.973  < 2e-16 ***
Site.L            -0.001939   0.006794  -0.285    0.779    
Genotype.L        -0.054191   0.008321  -6.513 4.01e-06 ***
Genotype.Q         0.003016   0.008321   0.362    0.721    
Site.L:Genotype.L -0.004362   0.011768  -0.371    0.715    
Site.L:Genotype.Q -0.005362   0.011768  -0.456    0.654    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.02354 on 18 degrees of freedom
Multiple R-squared:  0.7048,    Adjusted R-squared:  0.6228 
F-statistic: 8.594 on 5 and 18 DF,  p-value: 0.0002645
anova(Tol_ScoreF_M4_lm)
Analysis of Variance Table

Response: Score_Full.prop
              Df    Sum Sq   Mean Sq F value    Pr(>F)    
Site           1 0.0000451 0.0000451  0.0814    0.7786    
Genotype       2 0.0235660 0.0117830 21.2724 1.815e-05 ***
Site:Genotype  2 0.0001911 0.0000956  0.1725    0.8429    
Residuals     18 0.0099704 0.0005539                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreF_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 1.34e-03 | [0.00, 1.00]
Genotype      |     0.70 | [0.45, 1.00]
Site:Genotype | 5.66e-03 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreF_M4_lm.res<-data.frame(anova(Tol_ScoreF_M4_lm))
Tol_ScoreF_M4_lm.res$Predictor<-rownames(Tol_ScoreF_M4_lm.res)
Tol_ScoreF_M4_lm.res$EtaSq<-c(eta_squared(Tol_ScoreF_M4_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreF_M4_lm.res$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M4_lm.res))
Tol_ScoreF_M4_lm.res$TimeP<-rep("M4", nrow(Tol_ScoreF_M4_lm.res))
Tol_ScoreF_M4_lm.res<-Tol_ScoreF_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreF_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.991 0.0118 18    0.967    1.016
 AC12      0.947 0.0118 18    0.922    0.972
 AC8       0.919 0.0118 18    0.894    0.944

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.990 0.0118 18    0.965    1.015
 AC12      0.950 0.0118 18    0.926    0.975
 AC8       0.909 0.0118 18    0.884    0.934

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0445 0.0166 18   2.672  0.0393
 AC10 - AC8    0.0723 0.0166 18   4.343  0.0011
 AC12 - AC8    0.0278 0.0166 18   1.670  0.2434

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0396 0.0166 18   2.377  0.0705
 AC10 - AC8    0.0810 0.0166 18   4.867  0.0003
 AC12 - AC8    0.0415 0.0166 18   2.491  0.0564

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreF_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.991 0.0118 18    0.967    1.016
 SS    0.990 0.0118 18    0.965    1.015

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.947 0.0118 18    0.922    0.972
 SS    0.950 0.0118 18    0.926    0.975

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.919 0.0118 18    0.894    0.944
 SS    0.909 0.0118 18    0.884    0.934

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.00147 0.0166 18   0.089  0.9304

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00345 0.0166 18  -0.207  0.8381

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.01020 0.0166 18   0.613  0.5476
##Save p-values

#Genotypes within Sites
Tol_ScoreF_M4_lm.geno<-data.frame(emmeans(Tol_ScoreF_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreF_M4_lm.geno<-Tol_ScoreF_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M4_lm.geno$group1<-paste(Tol_ScoreF_M4_lm.geno$Site, Tol_ScoreF_M4_lm.geno$group1, sep="_")
Tol_ScoreF_M4_lm.geno$group2<-paste(Tol_ScoreF_M4_lm.geno$Site, Tol_ScoreF_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreF_M4_lm.site<-data.frame(emmeans(Tol_ScoreF_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreF_M4_lm.site<-Tol_ScoreF_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreF_M4_lm.site$group1<-paste(Tol_ScoreF_M4_lm.site$group1, Tol_ScoreF_M4_lm.site$Genotype, sep="_")
Tol_ScoreF_M4_lm.site$group2<-paste(Tol_ScoreF_M4_lm.site$group2, Tol_ScoreF_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreF_M4_lm.p<-rbind(Tol_ScoreF_M4_lm.geno[,c(1:2,4:8)], Tol_ScoreF_M4_lm.site[,c(1:2,4:8)])
Tol_ScoreF_M4_lm.p<-Tol_ScoreF_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreF_M4_lm.p$Sig<-ifelse(Tol_ScoreF_M4_lm.p$p<0.001, "***", ifelse(Tol_ScoreF_M4_lm.p$p<0.01, "**", ifelse(Tol_ScoreF_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreF_M4_lm.p$Response<-rep("Color_FullSet", nrow(Tol_ScoreF_M4_lm.p))
Tol_ScoreF_M4_lm.p$TimeP<-rep("M4", nrow(Tol_ScoreF_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreF_M4_SG<-summarySE(TolData_M4, measurevar="Score_Full.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreF_M4_SG.plot<-ggplot(Tol_ScoreF_M4_SG, aes(x=Site.Geno, y=Score_Full.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_Full.prop-se, ymax=Score_Full.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Color Retained (Full)")+
  ylim(0.6, 1.2)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreF_M4_lm.p,  y.position=1.05, step.increase=0.35, label="Sig", hide.ns=TRUE); Tol_ScoreF_M4_SG.plot

Thermal Tolerance Color by Timepoint

Full Set

Run Model

##Check normality
hist(TolData$Score_TP.prop)
shapiro.test(TolData$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData$Score_TP.prop
W = 0.95179, p-value = 0.009694
#Not Normal

##Try square transformation
hist((TolData$Score_TP.prop)^2)

shapiro.test((TolData$Score_TP.prop)^2)

    Shapiro-Wilk normality test

data:  (TolData$Score_TP.prop)^2
W = 0.95179, p-value = 0.009688
#Not normal 

##Try cubed transformation
hist((TolData$Score_TP.prop)^3)

shapiro.test((TolData$Score_TP.prop)^3)

    Shapiro-Wilk normality test

data:  (TolData$Score_TP.prop)^3
W = 0.95056, p-value = 0.00836
#Not normal 

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_lm)); qqline(resid(Tol_ScoreTP_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_lm), resid(Tol_ScoreTP_lm))

Model Results

#Model Results
summary(Tol_ScoreTP_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + TimeP + Site:Genotype + 
    Site:TimeP + Genotype:TimeP, data = TolData)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.133294 -0.019060  0.000725  0.026225  0.122906 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)         0.883494   0.006319 139.809  < 2e-16 ***
Site.L              0.038546   0.008912   4.325 6.47e-05 ***
Genotype.L         -0.102221   0.010797  -9.468 3.81e-13 ***
Genotype.Q          0.004971   0.011092   0.448 0.655784    
TimeP.L             0.068495   0.010797   6.344 4.45e-08 ***
TimeP.Q             0.021265   0.011092   1.917 0.060411 .  
Site.L:Genotype.L   0.014004   0.015269   0.917 0.363050    
Site.L:Genotype.Q  -0.008574   0.015625  -0.549 0.585424    
Site.L:TimeP.L     -0.036792   0.015269  -2.410 0.019344 *  
Site.L:TimeP.Q     -0.004886   0.015625  -0.313 0.755697    
Genotype.L:TimeP.L  0.029281   0.018818   1.556 0.125448    
Genotype.Q:TimeP.L  0.024642   0.018582   1.326 0.190292    
Genotype.L:TimeP.Q  0.015340   0.018582   0.826 0.412653    
Genotype.Q:TimeP.Q -0.072757   0.019821  -3.671 0.000548 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.05222 on 55 degrees of freedom
Multiple R-squared:  0.763, Adjusted R-squared:  0.7069 
F-statistic: 13.62 on 13 and 55 DF,  p-value: 8.098e-13
anova(Tol_ScoreTP_lm)
Analysis of Variance Table

Response: Score_TP.prop
               Df   Sum Sq  Mean Sq F value    Pr(>F)    
Site            1 0.057199 0.057199 20.9741 2.709e-05 ***
Genotype        2 0.238412 0.119206 43.7110 4.331e-12 ***
TimeP           2 0.117103 0.058552 21.4700 1.284e-07 ***
Site:Genotype   2 0.003221 0.001611  0.5906  0.557481    
Site:TimeP      2 0.017283 0.008642  3.1687  0.049832 *  
Genotype:TimeP  4 0.049580 0.012395  4.5450  0.003041 ** 
Residuals      55 0.149993 0.002727                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter      |     Eta2 |       95% CI
----------------------------------------
Site           |     0.09 | [0.01, 1.00]
Genotype       |     0.38 | [0.20, 1.00]
TimeP          |     0.19 | [0.04, 1.00]
Site:Genotype  | 5.09e-03 | [0.00, 1.00]
Site:TimeP     |     0.03 | [0.00, 1.00]
Genotype:TimeP |     0.08 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_lm.res<-data.frame(anova(Tol_ScoreTP_lm))
Tol_ScoreTP_lm.res$Predictor<-rownames(Tol_ScoreTP_lm.res)
Tol_ScoreTP_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_lm.res))
Tol_ScoreTP_lm.res<-Tol_ScoreTP_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Strong influence of Timepoint, including interactions with variables of interest, Site and Genotype. Will analyze each Timepoint individually.

Color Score by Timepoint Summer 1 Timepoint W2

Run Model

##Check normality
hist(TolData_W2$Score_TP.prop)

shapiro.test(TolData_W2$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_W2$Score_TP.prop
W = 0.95707, p-value = 0.4068
#Normal

##Model as a function of Site and Genotype
Tol_ScoreTP_W2_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_W2)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_W2_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_W2_lm)); qqline(resid(Tol_ScoreTP_W2_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_W2_lm), resid(Tol_ScoreTP_W2_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_W2_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_W2)

Residuals:
     Min       1Q   Median       3Q      Max 
-0.06045 -0.02293  0.00115  0.02314  0.07585 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.8997236  0.0084985 105.868  < 2e-16 ***
Site.L             0.0162968  0.0120187   1.356 0.192853    
Genotype.L        -0.0664798  0.0149123  -4.458 0.000345 ***
Genotype.Q        -0.0201334  0.0145249  -1.386 0.183620    
Site.L:Genotype.L  0.0005833  0.0210892   0.028 0.978255    
Site.L:Genotype.Q  0.0026173  0.0205413   0.127 0.900105    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.04052 on 17 degrees of freedom
Multiple R-squared:  0.5884,    Adjusted R-squared:  0.4674 
F-statistic: 4.861 on 5 and 17 DF,  p-value: 0.006075
anova(Tol_ScoreTP_W2_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq   Mean Sq F value    Pr(>F)    
Site           1 0.004491 0.0044907  2.7346 0.1165399    
Genotype       2 0.035398 0.0176991 10.7779 0.0009485 ***
Site:Genotype  2 0.000027 0.0000137  0.0084 0.9916821    
Residuals     17 0.027917 0.0016422                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_W2_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          |     0.07 | [0.00, 1.00]
Genotype      |     0.52 | [0.19, 1.00]
Site:Genotype | 4.05e-04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_W2_lm.res<-data.frame(anova(Tol_ScoreTP_W2_lm))
Tol_ScoreTP_W2_lm.res$Predictor<-rownames(Tol_ScoreTP_W2_lm.res)
Tol_ScoreTP_W2_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_W2_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_W2_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_W2_lm.res))
Tol_ScoreTP_W2_lm.res$TimeP<-rep("W2", nrow(Tol_ScoreTP_W2_lm.res))
Tol_ScoreTP_W2_lm.res<-Tol_ScoreTP_W2_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_W2_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.927 0.0203 17    0.884    0.969
 AC12      0.906 0.0203 17    0.863    0.949
 AC8       0.832 0.0203 17    0.789    0.875

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.951 0.0203 17    0.908    0.993
 AC12      0.926 0.0203 17    0.883    0.969
 AC8       0.857 0.0234 17    0.808    0.906

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0204 0.0287 17   0.711  0.7604
 AC10 - AC8    0.0946 0.0287 17   3.301  0.0111
 AC12 - AC8    0.0742 0.0287 17   2.590  0.0476

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0243 0.0287 17   0.849  0.6786
 AC10 - AC8    0.0934 0.0310 17   3.019  0.0201
 AC12 - AC8    0.0691 0.0310 17   2.233  0.0940

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_W2_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.927 0.0203 17    0.884    0.969
 SS    0.951 0.0203 17    0.908    0.993

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.906 0.0203 17    0.863    0.949
 SS    0.926 0.0203 17    0.883    0.969

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.832 0.0203 17    0.789    0.875
 SS    0.857 0.0234 17    0.808    0.906

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0240 0.0287 17  -0.837  0.4144

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0200 0.0287 17  -0.699  0.4941

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS   -0.0251 0.0310 17  -0.812  0.4278
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_W2_lm.geno<-data.frame(emmeans(Tol_ScoreTP_W2_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_W2_lm.geno<-Tol_ScoreTP_W2_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_W2_lm.geno$group1<-paste(Tol_ScoreTP_W2_lm.geno$Site, Tol_ScoreTP_W2_lm.geno$group1, sep="_")
Tol_ScoreTP_W2_lm.geno$group2<-paste(Tol_ScoreTP_W2_lm.geno$Site, Tol_ScoreTP_W2_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_W2_lm.site<-data.frame(emmeans(Tol_ScoreTP_W2_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_W2_lm.site<-Tol_ScoreTP_W2_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_W2_lm.site$group1<-paste(Tol_ScoreTP_W2_lm.site$group1, Tol_ScoreTP_W2_lm.site$Genotype, sep="_")
Tol_ScoreTP_W2_lm.site$group2<-paste(Tol_ScoreTP_W2_lm.site$group2, Tol_ScoreTP_W2_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_W2_lm.p<-rbind(Tol_ScoreTP_W2_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_W2_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_W2_lm.p<-Tol_ScoreTP_W2_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_W2_lm.p$Sig<-ifelse(Tol_ScoreTP_W2_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_W2_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_W2_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_W2_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_W2_lm.p))
Tol_ScoreTP_W2_lm.p$TimeP<-rep("W2", nrow(Tol_ScoreTP_W2_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_W2_SG<-summarySE(TolData_W2, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_W2_SG.plot<-ggplot(Tol_ScoreTP_W2_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Color Retained (TP)")+
  ylim(0.6, 1.2)+  
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_W2_lm.p,  y.position=1, step.increase=0.3, label="Sig", hide.ns=TRUE); Tol_ScoreTP_W2_SG.plot

Color Score by Timepoint Summer 2 Timepoint M1

Run Model

##Check normality
hist(TolData_M1$Score_TP.prop)

shapiro.test(TolData_M1$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_M1$Score_TP.prop
W = 0.92691, p-value = 0.1058
#Normal

##Model as a function of Site and Genotype
Tol_ScoreTP_M1_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_M1)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_M1_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_M1_lm)); qqline(resid(Tol_ScoreTP_M1_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_M1_lm), resid(Tol_ScoreTP_M1_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_M1_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M1)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.049233 -0.015825  0.003625  0.011990  0.071567 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.880342   0.006598 133.425  < 2e-16 ***
Site.L             0.020003   0.009331   2.144  0.04776 *  
Genotype.L        -0.076173   0.010842  -7.026 2.86e-06 ***
Genotype.Q         0.047387   0.011986   3.954  0.00114 ** 
Site.L:Genotype.L  0.019850   0.015332   1.295  0.21382    
Site.L:Genotype.Q  0.025394   0.016951   1.498  0.15357    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.03066 on 16 degrees of freedom
Multiple R-squared:  0.8232,    Adjusted R-squared:  0.768 
F-statistic:  14.9 on 5 and 16 DF,  p-value: 1.559e-05
anova(Tol_ScoreTP_M1_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq   Mean Sq F value    Pr(>F)    
Site           1 0.005270 0.0052700  5.6044   0.03086 *  
Genotype       2 0.061117 0.0305585 32.4976 2.319e-06 ***
Site:Genotype  2 0.003686 0.0018432  1.9602   0.17321    
Residuals     16 0.015045 0.0009403                      
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_M1_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     | Eta2 |       95% CI
-----------------------------------
Site          | 0.06 | [0.00, 1.00]
Genotype      | 0.72 | [0.47, 1.00]
Site:Genotype | 0.04 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_M1_lm.res<-data.frame(anova(Tol_ScoreTP_M1_lm))
Tol_ScoreTP_M1_lm.res$Predictor<-rownames(Tol_ScoreTP_M1_lm.res)
Tol_ScoreTP_M1_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_M1_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_M1_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M1_lm.res))
Tol_ScoreTP_M1_lm.res$TimeP<-rep("M1", nrow(Tol_ScoreTP_M1_lm.res))
Tol_ScoreTP_M1_lm.res<-Tol_ScoreTP_M1_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Site and Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_M1_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.942 0.0153 16    0.909    0.975
 AC12      0.842 0.0177 16    0.805    0.880
 AC8       0.814 0.0153 16    0.782    0.847

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.965 0.0153 16    0.933    0.998
 AC12      0.841 0.0177 16    0.804    0.879
 AC8       0.877 0.0153 16    0.845    0.910

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0998 0.0234 16   4.263  0.0016
 AC10 - AC8    0.1276 0.0217 16   5.884  0.0001
 AC12 - AC8    0.0277 0.0234 16   1.184  0.4789

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.1240 0.0234 16   5.293  0.0002
 AC10 - AC8    0.0879 0.0217 16   4.053  0.0025
 AC12 - AC8   -0.0361 0.0234 16  -1.541  0.2990

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_M1_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.942 0.0153 16    0.909    0.975
 SS    0.965 0.0153 16    0.933    0.998

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.842 0.0177 16    0.805    0.880
 SS    0.841 0.0177 16    0.804    0.879

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.814 0.0153 16    0.782    0.847
 SS    0.877 0.0153 16    0.845    0.910

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.02310 0.0217 16  -1.065  0.3025

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.00103 0.0250 16   0.041  0.9676

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.06280 0.0217 16  -2.896  0.0105
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_M1_lm.geno<-data.frame(emmeans(Tol_ScoreTP_M1_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_M1_lm.geno<-Tol_ScoreTP_M1_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M1_lm.geno$group1<-paste(Tol_ScoreTP_M1_lm.geno$Site, Tol_ScoreTP_M1_lm.geno$group1, sep="_")
Tol_ScoreTP_M1_lm.geno$group2<-paste(Tol_ScoreTP_M1_lm.geno$Site, Tol_ScoreTP_M1_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_M1_lm.site<-data.frame(emmeans(Tol_ScoreTP_M1_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_M1_lm.site<-Tol_ScoreTP_M1_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M1_lm.site$group1<-paste(Tol_ScoreTP_M1_lm.site$group1, Tol_ScoreTP_M1_lm.site$Genotype, sep="_")
Tol_ScoreTP_M1_lm.site$group2<-paste(Tol_ScoreTP_M1_lm.site$group2, Tol_ScoreTP_M1_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_M1_lm.p<-rbind(Tol_ScoreTP_M1_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_M1_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_M1_lm.p<-Tol_ScoreTP_M1_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_M1_lm.p$Sig<-ifelse(Tol_ScoreTP_M1_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_M1_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_M1_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_M1_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M1_lm.p))
Tol_ScoreTP_M1_lm.p$TimeP<-rep("M1", nrow(Tol_ScoreTP_M1_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_M1_SG<-summarySE(TolData_M1, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_M1_SG.plot<-ggplot(Tol_ScoreTP_M1_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Color Retained (TP)")+
  ylim(0.6, 1.2)+  
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M1_lm.p,  y.position=1, step.increase=0.25, label="Sig", hide.ns=TRUE); Tol_ScoreTP_M1_SG.plot

Color Score by Timepoint Winter Timepoint M4

Run Model

##Check normality
hist(TolData_M4$Score_TP.prop)

shapiro.test(TolData_M4$Score_TP.prop)

    Shapiro-Wilk normality test

data:  TolData_M4$Score_TP.prop
W = 0.92944, p-value = 0.09471
#Normal

##Model as a function of Site and Genotype
Tol_ScoreTP_M4_lm<-lm(Score_TP.prop~Site+Genotype+Site:Genotype, data=TolData_M4)

Check Residuals

##Check Normality of Residuals
#Distribution 
plot(density(resid(Tol_ScoreTP_M4_lm)))


#Q-Q plot
qqnorm(resid(Tol_ScoreTP_M4_lm)); qqline(resid(Tol_ScoreTP_M4_lm))


##Check Variance of Residuals across Fitted Values
plot(fitted(Tol_ScoreTP_M4_lm), resid(Tol_ScoreTP_M4_lm))

Model Results

Overall

#Model Results
summary(Tol_ScoreTP_M4_lm)

Call:
lm(formula = Score_TP.prop ~ Site + Genotype + Site:Genotype, 
    data = TolData_M4)

Residuals:
      Min        1Q    Median        3Q       Max 
-0.107100 -0.019856  0.004288  0.021244  0.073300 

Coefficients:
                   Estimate Std. Error t value Pr(>|t|)    
(Intercept)        0.914738   0.009447  96.827  < 2e-16 ***
Site.L             0.002646   0.013360   0.198 0.845240    
Genotype.L        -0.073451   0.016363  -4.489 0.000284 ***
Genotype.Q         0.001990   0.016363   0.122 0.904540    
Site.L:Genotype.L -0.016375   0.023141  -0.708 0.488238    
Site.L:Genotype.Q  0.026775   0.023141   1.157 0.262382    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.04628 on 18 degrees of freedom
Multiple R-squared:  0.5505,    Adjusted R-squared:  0.4256 
F-statistic: 4.409 on 5 and 18 DF,  p-value: 0.008508
anova(Tol_ScoreTP_M4_lm)
Analysis of Variance Table

Response: Score_TP.prop
              Df   Sum Sq  Mean Sq F value   Pr(>F)   
Site           1 0.000084 0.000084  0.0392 0.845240   
Genotype       2 0.043192 0.021596 10.0823 0.001155 **
Site:Genotype  2 0.003940 0.001970  0.9197 0.416564   
Residuals     18 0.038555 0.002142                    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#Effect Size of Predictors
eta_squared(Tol_ScoreTP_M4_lm, partial=FALSE)
# Effect Size for ANOVA (Type I)

Parameter     |     Eta2 |       95% CI
---------------------------------------
Site          | 9.79e-04 | [0.00, 1.00]
Genotype      |     0.50 | [0.18, 1.00]
Site:Genotype |     0.05 | [0.00, 1.00]

- One-sided CIs: upper bound fixed at [1.00].
##Save model results
Tol_ScoreTP_M4_lm.res<-data.frame(anova(Tol_ScoreTP_M4_lm))
Tol_ScoreTP_M4_lm.res$Predictor<-rownames(Tol_ScoreTP_M4_lm.res)
Tol_ScoreTP_M4_lm.res$EtaSq<-c(eta_squared(Tol_ScoreTP_M4_lm, partial=FALSE)$Eta2, NA)
Tol_ScoreTP_M4_lm.res$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M4_lm.res))
Tol_ScoreTP_M4_lm.res$TimeP<-rep("M4", nrow(Tol_ScoreTP_M4_lm.res))
Tol_ScoreTP_M4_lm.res<-Tol_ScoreTP_M4_lm.res %>% dplyr::rename( p.value = "Pr..F.", DF= "Df")

Significant effect of Genotype. Still checking Site*Genotype for comparability across Timepoints.

Pairwise

#Pairwise comparisons across:

#Genotypes within Sites
emmeans(Tol_ScoreTP_M4_lm, pairwise~Genotype | Site)
$emmeans
Site = KL:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.950 0.0231 18    0.901    0.998
 AC12      0.927 0.0231 18    0.878    0.975
 AC8       0.862 0.0231 18    0.814    0.911

Site = SS:
 Genotype emmean     SE df lower.CL upper.CL
 AC10      0.985 0.0231 18    0.937    1.034
 AC12      0.900 0.0231 18    0.851    0.948
 AC8       0.865 0.0231 18    0.816    0.914

Confidence level used: 0.95 

$contrasts
Site = KL:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0230 0.0327 18   0.703  0.7649
 AC10 - AC8    0.0875 0.0327 18   2.674  0.0392
 AC12 - AC8    0.0645 0.0327 18   1.971  0.1482

Site = SS:
 contrast    estimate     SE df t.ratio p.value
 AC10 - AC12   0.0858 0.0327 18   2.620  0.0437
 AC10 - AC8    0.1202 0.0327 18   3.674  0.0047
 AC12 - AC8    0.0345 0.0327 18   1.054  0.5536

P value adjustment: tukey method for comparing a family of 3 estimates 
#Sites within Genotypes
emmeans(Tol_ScoreTP_M4_lm, pairwise~Site | Genotype)
$emmeans
Genotype = AC10:
 Site emmean     SE df lower.CL upper.CL
 KL    0.950 0.0231 18    0.901    0.998
 SS    0.985 0.0231 18    0.937    1.034

Genotype = AC12:
 Site emmean     SE df lower.CL upper.CL
 KL    0.927 0.0231 18    0.878    0.975
 SS    0.900 0.0231 18    0.851    0.948

Genotype = AC8:
 Site emmean     SE df lower.CL upper.CL
 KL    0.862 0.0231 18    0.814    0.911
 SS    0.865 0.0231 18    0.816    0.914

Confidence level used: 0.95 

$contrasts
Genotype = AC10:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.03558 0.0327 18  -1.087  0.2914

Genotype = AC12:
 contrast estimate     SE df t.ratio p.value
 KL - SS   0.02718 0.0327 18   0.830  0.4172

Genotype = AC8:
 contrast estimate     SE df t.ratio p.value
 KL - SS  -0.00282 0.0327 18  -0.086  0.9322
##Save p-values

#Genotypes within Sites
Tol_ScoreTP_M4_lm.geno<-data.frame(emmeans(Tol_ScoreTP_M4_lm, pairwise~Genotype | Site)$contrasts)
Tol_ScoreTP_M4_lm.geno<-Tol_ScoreTP_M4_lm.geno %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M4_lm.geno$group1<-paste(Tol_ScoreTP_M4_lm.geno$Site, Tol_ScoreTP_M4_lm.geno$group1, sep="_")
Tol_ScoreTP_M4_lm.geno$group2<-paste(Tol_ScoreTP_M4_lm.geno$Site, Tol_ScoreTP_M4_lm.geno$group2, sep="_")

#Sites within Genotypes
Tol_ScoreTP_M4_lm.site<-data.frame(emmeans(Tol_ScoreTP_M4_lm, pairwise~Site | Genotype)$contrasts)
Tol_ScoreTP_M4_lm.site<-Tol_ScoreTP_M4_lm.site %>% separate(col=contrast, into=c("group1", "group2"), sep=" - ", remove=TRUE)
Tol_ScoreTP_M4_lm.site$group1<-paste(Tol_ScoreTP_M4_lm.site$group1, Tol_ScoreTP_M4_lm.site$Genotype, sep="_")
Tol_ScoreTP_M4_lm.site$group2<-paste(Tol_ScoreTP_M4_lm.site$group2, Tol_ScoreTP_M4_lm.site$Genotype, sep="_")

#Full list of p-values
Tol_ScoreTP_M4_lm.p<-rbind(Tol_ScoreTP_M4_lm.geno[,c(1:2,4:8)], Tol_ScoreTP_M4_lm.site[,c(1:2,4:8)])
Tol_ScoreTP_M4_lm.p<-Tol_ScoreTP_M4_lm.p %>% dplyr::rename( p = p.value)

#Add Significance Levels
Tol_ScoreTP_M4_lm.p$Sig<-ifelse(Tol_ScoreTP_M4_lm.p$p<0.001, "***", ifelse(Tol_ScoreTP_M4_lm.p$p<0.01, "**", ifelse(Tol_ScoreTP_M4_lm.p$p<0.05, "*", NA)))

#Specify Response and Timepoint
Tol_ScoreTP_M4_lm.p$Response<-rep("Color_TP", nrow(Tol_ScoreTP_M4_lm.p))
Tol_ScoreTP_M4_lm.p$TimeP<-rep("M4", nrow(Tol_ScoreTP_M4_lm.p))

Plot Retention by Site and Genotype

##Summary statistics by Site and Genotype
Tol_ScoreTP_M4_SG<-summarySE(TolData_M4, measurevar="Score_TP.prop", groupvars=c("Site.Geno", "Site", "Genotype"), na.rm=TRUE)

##Plot Average Retention across Treatments
Tol_ScoreTP_M4_SG.plot<-ggplot(Tol_ScoreTP_M4_SG, aes(x=Site.Geno, y=Score_TP.prop, colour=Genotype)) + 
  geom_errorbar(aes(ymin=Score_TP.prop-se, ymax=Score_TP.prop+se), width=cap.sz, linewidth=bar.sz)+
  geom_point(size=point.sz)+ 
  theme_classic()+
  theme( axis.title.x = element_text(size = axis.title.sz), 
         axis.title.y = element_text(size = axis.title.sz), 
        axis.text.x=element_text(size=axis.txt.sz, colour="black"),
        axis.text.y=element_text(size=axis.txt.sz, colour="black"), 
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        legend.box.background = element_rect(color = "black"),
        legend.position="bottom", 
        legend.direction="horizontal",
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="Proportion Color Retained (TP)")+
  ylim(0.6, 1.2)+ 
  scale_x_discrete(labels=c("","Klein","","","Something Special",""))+
  scale_color_manual(values = Geno.colors.o)+ 
  stat_pvalue_manual(data=Tol_ScoreTP_M4_lm.p,  y.position=1, step.increase=0.3, label="Sig", hide.ns=TRUE); Tol_ScoreTP_M4_SG.plot

Contrasts Across Metrics

Combine Contrast Results

Creating a heatmap to compare the direction and significance of pairwise comparisons across Tolerance metrics. Positive estimates indicate that Group 1 > Group 2. P values of less than 0.05 are considered significant.

##Combine Results
Tol_contrasts<-rbind(Tol_Chl_W2_lm.p, Tol_Chl_M1_lm.p, Tol_Chl_M4_lm.p, 
                     Tol_Sym_W2_lm.p, Tol_Sym_M1_lm.p, Tol_Sym_M4_lm.p, 
                     Tol_ScoreF_W2_lm.p, Tol_ScoreF_M1_lm.p, Tol_ScoreF_M4_lm.p, 
                     Tol_ScoreTP_W2_lm.p, Tol_ScoreTP_M1_lm.p, Tol_ScoreTP_M4_lm.p)

##Create Contrast Column
Tol_contrasts$Contrast<-paste(Tol_contrasts$group1, Tol_contrasts$group2, sep=" v. ")

##Add Set column with Contrast and Timepoint
Tol_contrasts$Set<-paste(Tol_contrasts$TimeP, Tol_contrasts$Contrast, sep=" ")

##Re-order by Seasonal Timepoint
Tol_contrasts$TimeP<-factor(Tol_contrasts$TimeP, levels=c("W2", "M1", "M4"), ordered=TRUE)
Tol_contrasts<- Tol_contrasts %>% arrange(desc(as.numeric(TimeP)))

Tol_contrasts$Set<-factor(Tol_contrasts$Set, levels=c(unique(Tol_contrasts$Set)), ordered=TRUE)

Standardize Response Scale

Convert Estimate to the Response scale (instead of log +1 scale) for models where the response was log transformed

Tol_contrasts$Estimate<-Tol_contrasts$estimate

#Chl M4
Tol_contrasts$Estimate[which(Tol_contrasts$Response=="Chlorophyll" & Tol_contrasts$TimeP=="M4")]<-c(exp(Tol_contrasts$estimate[which(Tol_contrasts$Response=="Chlorophyll" & Tol_contrasts$TimeP=="M4")])-1)

#Sym M1
Tol_contrasts$Estimate[which(Tol_contrasts$Response=="Symbionts" & Tol_contrasts$TimeP=="M1")]<-c(exp(Tol_contrasts$estimate[which(Tol_contrasts$Response=="Symbionts" & Tol_contrasts$TimeP=="M1")])-1)

Contrast Heatmaps

Summer 1 Timepoint W2

Tol_Pairs_W2.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="W2"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Summer 1")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_W2.plot

Summer 2 Timepoint M1

Tol_Pairs_M1.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="M1"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Summer 2")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_M1.plot

Winter Timepoint M4

Tol_Pairs_M4.plot<-ggplot(data=Tol_contrasts[which(Tol_contrasts$TimeP=="M4"),], aes(x=Response, y=Contrast, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts Month 4")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_M4.plot

All Timepoints

Tol_Pairs.plot<-ggplot(data=Tol_contrasts, aes(x=Response, y=Set, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Pairwise Contrasts")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs.plot

Significant Differences

Subsetting Contrasts to only include contrasts with significant differences in at least one of the thermal tolerance metrics (Chlorophyll or Symbiont or Color retention)

##Remove rows with non-significant p-values
Tol_contrasts_sig<-subset(Tol_contrasts, p < 0.05)

##Keep Sets where at least one metric shows a significant difference
Tol_Sets_sig<-data.frame(Set=c(unique(Tol_contrasts_sig$Set)))
Tol_contrasts_sig_Set<-merge(Tol_Sets_sig, Tol_contrasts, all.x=TRUE, all.y=FALSE)
Tol_Pairs_sig.plot<-ggplot(data=Tol_contrasts_sig_Set, aes(x=Response, y=Set, fill=Estimate))+
  geom_tile()+
  geom_text(aes(label=Sig), size=sig.sz)+
  scale_fill_gradient2(low="#BA1E02FF", mid="white", high="#3BA0FDFF")+
  theme_bw()+
  ggtitle("Significant Pairwise Contrasts")+
  theme(axis.text.x=element_text(size=axis.title.sz, colour="black", angle=45, hjust=1),
        axis.text.y=element_text(size=axis.txt.sz-1, colour="black"),
        legend.text=element_text(size=leg.txt.sz),
        legend.title=element_text(size=leg.title.sz), 
        plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))+
  labs(x="", y="", fill="Estimate");Tol_Pairs_sig.plot

Proportion of Agreement

Assessing the proportion of agreement between methods as the pairwise comparisons where two methods both find a significant difference out of the total pairwise comparisons. Calculating the proportion of agreement between Chlorophyll and Color Full Set, Chlorophyll and Color Timepoint, Symbionts and Color Full Set, Symbionts and Color Timepoint, and Chlorophyll and Symbionts. Comparing the proportion of agreement between methods of quantifying thermal tolerance.

names(Tol_contrasts)
 [1] "group1"   "group2"   "estimate" "SE"       "df"       "t.ratio"  "p"        "Sig"     
 [9] "Response" "TimeP"    "Contrast" "Set"      "Estimate"
##Change long to short format
Tol_contrasts.agree<-Tol_contrasts %>% pivot_wider(names_from="Response", values_from=c("p", "Estimate"), id_cols=c("TimeP", "Contrast", "Set"))

##Convert p values to binary
#0: No significant difference (p>0.05) detected in that pairwise contrast
#1: Significant difference (p<0.05) detected in that pairwise contrast
Tol_contrasts.agree[,c(4:7)]<-ifelse(Tol_contrasts.agree[,c(4:7)]<0.05, 1, 0)

##Convert estimates to Greater or Less
#Greater: Positive estimates indicate A>B in the Contrast
#Less: Negative estimates indicate A<B in the Contrast
Tol_contrasts.agree[,c(8:11)]<-ifelse(Tol_contrasts.agree[,c(8:11)]<0, "Less", "Greater")

##Identify agreement
#1: Both metrics identified a significant difference in that pairwise contrast OR Neither metric identified a significant difference
#0: One metrics identified a significant difference in that pairwise contrast
#For each matching case (1), confirm matching Estimates
Tol_contrasts.agree$Chl.Sym<-ifelse(Tol_contrasts.agree$p_Chlorophyll==1 &
Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Symbionts &
Tol_contrasts.agree$Estimate_Chlorophyll==Tol_contrasts.agree$Estimate_Symbionts, 1, 
ifelse(Tol_contrasts.agree$p_Chlorophyll==0 & 
         Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Symbionts, 1, 0))

Tol_contrasts.agree$Chl.ColF<-ifelse(Tol_contrasts.agree$p_Chlorophyll==1 &                                     Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_FullSet &
Tol_contrasts.agree$Estimate_Chlorophyll==Tol_contrasts.agree$Estimate_Color_FullSet, 1, 
ifelse(Tol_contrasts.agree$p_Chlorophyll==0 &
         Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_FullSet, 1, 0))

Tol_contrasts.agree$Chl.ColTP<-ifelse(Tol_contrasts.agree$p_Chlorophyll==1 & 
Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_TP &                          Tol_contrasts.agree$Estimate_Chlorophyll==Tol_contrasts.agree$Estimate_Color_TP, 1, 
ifelse(Tol_contrasts.agree$p_Chlorophyll==0 &
         Tol_contrasts.agree$p_Chlorophyll==Tol_contrasts.agree$p_Color_TP, 1, 0))

Tol_contrasts.agree$Sym.ColF<-ifelse(Tol_contrasts.agree$p_Symbionts==1 &
Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_FullSet & Tol_contrasts.agree$Estimate_Symbionts==Tol_contrasts.agree$Estimate_Color_FullSet, 1,
ifelse(Tol_contrasts.agree$p_Symbionts==0 &
         Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_FullSet, 1, 0))

Tol_contrasts.agree$Sym.ColTP<-ifelse(Tol_contrasts.agree$p_Symbionts==1 &
Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_TP & Tol_contrasts.agree$Estimate_Symbionts==Tol_contrasts.agree$Estimate_Color_TP, 1,
ifelse(Tol_contrasts.agree$p_Symbionts==0 &
         Tol_contrasts.agree$p_Symbionts==Tol_contrasts.agree$p_Color_TP, 1, 0))

Tol_contrasts.agree$ColF.ColTP<-ifelse(Tol_contrasts.agree$p_Color_FullSet==1 &
Tol_contrasts.agree$p_Color_FullSet==Tol_contrasts.agree$p_Color_TP & Tol_contrasts.agree$Estimate_Color_FullSet==Tol_contrasts.agree$Estimate_Color_TP, 1, 
ifelse(Tol_contrasts.agree$p_Color_FullSet==0 &
         Tol_contrasts.agree$p_Color_FullSet==Tol_contrasts.agree$p_Color_TP, 1, 0))

##Convert to long to calculate instances of agreement
Tol_contrasts.agree.long<-Tol_contrasts.agree %>% pivot_longer(cols=c("Chl.Sym", "Chl.ColF", "Chl.ColTP", "Sym.ColF", "Sym.ColTP", "ColF.ColTP"), names_to="Compare", values_to="Agree")

##Sum Cases of Agreement
Tol_contrasts.agree.sum<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$Compare), sum)
names(Tol_contrasts.agree.sum)<-c("Compare", "Agree")

##Total Pairwise Comparisons
Tol_contrasts.agree.sum$Total<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$Compare), function(x) length(x))[,2]

Compare Proportion Agreement

prop.test(Tol_contrasts.agree.sum$Agree, Tol_contrasts.agree.sum$Total)

    6-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.sum$Agree out of Tol_contrasts.agree.sum$Total
X-squared = 2.8177, df = 5, p-value = 0.7281
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3    prop 4    prop 5    prop 6 
0.7037037 0.7407407 0.7037037 0.8518519 0.6666667 0.7407407 

No significant difference in the proportion of agreement in detecting pairwise differences in thermal tolerance across comparisons of traditional bleaching or color score methods (Pearson’s chi-squared test p-value = 0.7281)

Compare Agreement across Seasons

##Sum Cases of Agreement by Comparison and Timepoint
Tol_contrasts.agree.sum.tp<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$TimeP, Tol_contrasts.agree.long$Compare), sum)
names(Tol_contrasts.agree.sum.tp)<-c("TimeP", "Compare", "Agree")

##Total Pairwise Comparisons
Tol_contrasts.agree.sum.tp$Total<-aggregate(Tol_contrasts.agree.long$Agree, list(Tol_contrasts.agree.long$TimeP, Tol_contrasts.agree.long$Compare), function(x) length(x))[,3]

Chl vs Sym

##Subset by Comparison
Tol_contrasts.agree.Chl.Sym<-subset(Tol_contrasts.agree.sum.tp, Compare=="Chl.Sym")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Chl.Sym$Agree, Tol_contrasts.agree.Chl.Sym$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Chl.Sym$Agree out of Tol_contrasts.agree.Chl.Sym$Total
X-squared = 5.6842, df = 2, p-value = 0.0583
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.5555556 1.0000000 0.5555556 

Chl vs Color Full

##Subset by Comparison
Tol_contrasts.agree.Chl.ColF<-subset(Tol_contrasts.agree.sum.tp, Compare=="Chl.ColF")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Chl.ColF$Agree, Tol_contrasts.agree.Chl.ColF$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Chl.ColF$Agree out of Tol_contrasts.agree.Chl.ColF$Total
X-squared = 9.9474, df = 2, p-value = 0.006918
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
1.0000000 0.7777778 0.3333333 

Chl vs Color Timepoint

##Subset by Comparison
Tol_contrasts.agree.Chl.ColTP<-subset(Tol_contrasts.agree.sum.tp, Compare=="Chl.ColTP")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Chl.ColTP$Agree, Tol_contrasts.agree.Chl.ColTP$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Chl.ColTP$Agree out of Tol_contrasts.agree.Chl.ColTP$Total
X-squared = 18.9, df = 2, p-value = 7.869e-05
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
1.0000000 1.0000000 0.2222222 

Sym vs Color Full

##Subset by Comparison
Tol_contrasts.agree.Sym.ColF<-subset(Tol_contrasts.agree.sum.tp, Compare=="Sym.ColF")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Sym.ColF$Agree, Tol_contrasts.agree.Sym.ColF$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Sym.ColF$Agree out of Tol_contrasts.agree.Sym.ColF$Total
X-squared = 1, df = 2, p-value = 0.6065
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.5555556 0.7777778 0.6666667 

Sym vs Color Timepoint

##Subset by Comparison
Tol_contrasts.agree.Sym.ColTP<-subset(Tol_contrasts.agree.sum.tp, Compare=="Sym.ColTP")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.Sym.ColTP$Agree, Tol_contrasts.agree.Sym.ColTP$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.Sym.ColTP$Agree out of Tol_contrasts.agree.Sym.ColTP$Total
X-squared = 5.0143, df = 2, p-value = 0.0815
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
0.5555556 1.0000000 0.6666667 

Color Full vs Color Timepoint

##Subset by Comparison
Tol_contrasts.agree.ColF.ColTP<-subset(Tol_contrasts.agree.sum.tp, Compare=="ColF.ColTP")

##Compare Proportions between Timepoints
prop.test(Tol_contrasts.agree.ColF.ColTP$Agree, Tol_contrasts.agree.ColF.ColTP$Total)
Warning: Chi-squared approximation may be incorrect

    3-sample test for equality of proportions without continuity correction

data:  Tol_contrasts.agree.ColF.ColTP$Agree out of Tol_contrasts.agree.ColF.ColTP$Total
X-squared = 2.3478, df = 2, p-value = 0.3092
alternative hypothesis: two.sided
sample estimates:
   prop 1    prop 2    prop 3 
1.0000000 0.7777778 0.7777778 

Figures

Figure S2 Tolerance Across Metrics

Update for Panel


##Top row
Tol_Chl_W2_SG.plot<-Tol_Chl_W2_SG.plot + ggtitle("Summer 1") +  labs(x="")+ 
  theme(legend.position="top", legend.direction="horizontal", plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))

Tol_Chl_M1_SG.plot<-Tol_Chl_M1_SG.plot + ggtitle("Summer 2") +  labs(x="", y="")+ 
  theme(legend.position="top", legend.direction="horizontal", plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))
  
Tol_Chl_M4_SG.plot<-Tol_Chl_M4_SG.plot + ggtitle("Winter") +  labs(x="", y="")+ 
  theme(legend.position="top", legend.direction="horizontal", plot.title = element_text(size = plot.title.sz, colour="black", hjust = 0.5))
  
##Bottom row
Tol_Sym_W2_SG.plot<-Tol_Sym_W2_SG.plot+labs(x="Site and Genotype")+ theme(legend.position="none")

Tol_Sym_M1_SG.plot<-Tol_Sym_M1_SG.plot+labs(x="Site and Genotype", y="")+ theme(legend.position="none")

Tol_Sym_M4_SG.plot<-Tol_Sym_M4_SG.plot+labs(x="Site and Genotype", y="")+ theme(legend.position="none")


##Color scores
Tol_ScoreF_W2_SG.plot<-Tol_ScoreF_W2_SG.plot+labs(x="")+ theme(legend.position="none")

Tol_ScoreF_M1_SG.plot<-Tol_ScoreF_M1_SG.plot+labs(x="", y="")+ theme(legend.position="none")

Tol_ScoreF_M4_SG.plot<-Tol_ScoreF_M4_SG.plot+labs(x="", y="")+ theme(legend.position="none")


Tol_ScoreTP_W2_SG.plot<-Tol_ScoreTP_W2_SG.plot+labs(x="")+ theme(legend.position="none")

Tol_ScoreTP_M1_SG.plot<-Tol_ScoreTP_M1_SG.plot+labs(x="", y="")+ theme(legend.position="none")

Tol_ScoreTP_M4_SG.plot<-Tol_ScoreTP_M4_SG.plot+labs(x="", y="")+ theme(legend.position="none")

Figure S2

##Create Panel
Tolerance_fig<-plot_grid(Tol_Chl_W2_SG.plot, Tol_Chl_M1_SG.plot, Tol_Chl_M4_SG.plot,
                  Tol_ScoreF_W2_SG.plot, Tol_ScoreF_M1_SG.plot, Tol_ScoreF_M4_SG.plot,
                  Tol_ScoreTP_W2_SG.plot, Tol_ScoreTP_M1_SG.plot, Tol_ScoreTP_M4_SG.plot,
                  Tol_Sym_W2_SG.plot, Tol_Sym_M1_SG.plot, Tol_Sym_M4_SG.plot,
                        nrow=4, ncol=3, byrow=TRUE,
                        rel_widths=1,
                        rel_heights=c(1, 0.85, 0.85, 0.85), 
                        labels=c("a", "b", "c", 
                                 "d", "e", "f", 
                                 "g", "h", "i", 
                                 "j", "k", "l"), 
                        label_size=panel.lab.sz, 
                        label_fontface = "bold")

##Save Figure
ggsave(filename="Figures/FigureS2_Tolerance_Across_Metrics.png", plot=Tolerance_fig, dpi=300, width=14, height=20, units="in")

Figure 4 Contrasts Heatmap

##Save Figure
ggsave(filename="Figures/Figure4_Tolerance_Heatmap.png", plot=Tol_Pairs.plot, dpi=300, width=8, height=12, units="in")

Tables

Table S2 Linear Model Results

##Combine Results Tables
TableS2_Tol.lm.res<-rbind(Tol_Chl_W2_lm.res, Tol_Chl_M1_lm.res, Tol_Chl_M4_lm.res,
                        Tol_Sym_W2_lm.res, Tol_Sym_M1_lm.res, Tol_Sym_M4_lm.res,
                        Tol_ScoreF_W2_lm.res, Tol_ScoreF_M1_lm.res, Tol_ScoreF_M4_lm.res,
                    Tol_ScoreTP_W2_lm.res, Tol_ScoreTP_M1_lm.res, Tol_ScoreTP_M4_lm.res)

##Add a Season Variable
TableS2_Tol.lm.res$Season<-ifelse(TableS2_Tol.lm.res$TimeP=="W2", "Summer1", ifelse(TableS2_Tol.lm.res$TimeP=="M1", "Summer2", ifelse(TableS2_Tol.lm.res$TimeP=="M4", "Winter" , NA)))

##Organize
names(TableS2_Tol.lm.res)
 [1] "DF"        "Sum.Sq"    "Mean.Sq"   "F.value"   "p.value"   "Predictor" "EtaSq"    
 [8] "Response"  "TimeP"     "Season"   
TableS2_Tol.lm.res<-TableS2_Tol.lm.res[,c("TimeP", "Season", "Response", "Predictor", "DF", "Sum.Sq", "Mean.Sq", "F.value", "p.value", "EtaSq")]

#Round to 4 digits
TableS2_Tol.lm.res$Sum.Sq<-round(TableS2_Tol.lm.res$Sum.Sq, 4)
TableS2_Tol.lm.res$Mean.Sq<-round(TableS2_Tol.lm.res$Mean.Sq, 4)
TableS2_Tol.lm.res$F.value<-round(TableS2_Tol.lm.res$F.value, 4)
TableS2_Tol.lm.res$p.value<-round(TableS2_Tol.lm.res$p.value, 4)
TableS2_Tol.lm.res$EtaSq<-round(TableS2_Tol.lm.res$EtaSq, 4)

##Write Out Table
write.csv(TableS2_Tol.lm.res, "Tables/TableS2_Tolerance_LM_Results.csv", row.names=FALSE)

Table S3 Pairwise Comparison Results

##Pairwise Results Table
TableS3_Tol.pairwise<-Tol_contrasts

##Add a Season Variable
TableS3_Tol.pairwise$Season<-ifelse(TableS3_Tol.pairwise$TimeP=="W2", "Summer1", ifelse(TableS3_Tol.pairwise$TimeP=="M1", "Summer2", ifelse(TableS3_Tol.pairwise$TimeP=="M4", "Winter" , NA)))

##Re-order by Seasonal Timepoint
TableS3_Tol.pairwise<- TableS3_Tol.pairwise %>% arrange(as.numeric(TimeP))

##Organize
names(TableS3_Tol.pairwise)
 [1] "group1"   "group2"   "estimate" "SE"       "df"       "t.ratio"  "p"        "Sig"     
 [9] "Response" "TimeP"    "Contrast" "Set"      "Estimate" "Season"  
TableS3_Tol.pairwise<-TableS3_Tol.pairwise[,c("TimeP", "Season", "Response", "Contrast", "Estimate", "SE", "df", "t.ratio", "p")]
TableS3_Tol.pairwise<-TableS3_Tol.pairwise %>% dplyr::rename( DF = df) %>% dplyr::rename( p.value = p)

#Round to 4 digits
TableS3_Tol.pairwise$Estimate<-round(TableS3_Tol.pairwise$Estimate, 4)
TableS3_Tol.pairwise$SE<-round(TableS3_Tol.pairwise$SE, 4)
TableS3_Tol.pairwise$t.ratio<-round(TableS3_Tol.pairwise$t.ratio, 4)
TableS3_Tol.pairwise$p.value<-round(TableS3_Tol.pairwise$p.value, 4)

##Write Out Table
write.csv(TableS3_Tol.pairwise, "Tables/TableS3_Tolerance_Pairwise_Results.csv", row.names=FALSE)
LS0tDQp0aXRsZTogIlRoZXJtYWwgVG9sZXJhbmNlIHdpdGggQ29sb3IgU2NvcmUgYW5kIEJsZWFjaGluZyBNZXRyaWNzIg0KYXV0aG9yOiAiU2VyZW5hIEhhY2tlcm90dCBhbmQgTGF1cmVuIEdyZWdvcnkiDQpkYXRlOiAiNy8xOS8yMDI0Ig0Kb3V0cHV0Og0KICBodG1sX2RvY3VtZW50Og0KICAgIHRvYzogeWVzDQogICAgZGZfcHJpbnQ6IHBhZ2VkDQogIGh0bWxfbm90ZWJvb2s6DQogICAgdG9jOiB5ZXMNCiAgICB0b2NfZmxvYXQ6IHllcw0KLS0tDQoNCiMgU2V0dXANCmBgYHtyIFNldHVwLCBpbmNsdWRlID0gRkFMU0V9DQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFKQ0KYGBgDQoNCg0KIyMjIExvYWQgUGFja2FnZXMNCmBgYHtyfQ0KIyNJbnN0YWxsIFBhY2thZ2VzIGlmIE5lZWRlZA0KaWYgKCFyZXF1aXJlKCJnZ3Bsb3QyIikpIGluc3RhbGwucGFja2FnZXMoImdncGxvdDIiKQ0KaWYgKCFyZXF1aXJlKCJlZmZlY3RzaXplIikpIGluc3RhbGwucGFja2FnZXMoImVmZmVjdHNpemUiKQ0KaWYgKCFyZXF1aXJlKCJlbW1lYW5zIikpIGluc3RhbGwucGFja2FnZXMoImVtbWVhbnMiKQ0KaWYgKCFyZXF1aXJlKCJkcGx5ciIpKSBpbnN0YWxsLnBhY2thZ2VzKCJkcGx5ciIpDQppZiAoIXJlcXVpcmUoInRpZHlyIikpIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCmlmICghcmVxdWlyZSgiUm1pc2MiKSkgaW5zdGFsbC5wYWNrYWdlcygiUm1pc2MiKQ0KaWYgKCFyZXF1aXJlKCJnZ3B1YnIiKSkgaW5zdGFsbC5wYWNrYWdlcygiZ2dwdWJyIikNCmlmICghcmVxdWlyZSgiY293cGxvdCIpKSBpbnN0YWxsLnBhY2thZ2VzKCJjb3dwbG90IikNCmlmICghcmVxdWlyZSgiZ3JpZEdyYXBoaWNzIikpIGluc3RhbGwucGFja2FnZXMoImdyaWRHcmFwaGljcyIpDQppZiAoIXJlcXVpcmUoInRpZHlyIikpIGluc3RhbGwucGFja2FnZXMoInRpZHlyIikNCg0KIyNMb2FkIFBhY2thZ2VzDQpsaWJyYXJ5KGdncGxvdDIpICNSZXF1aXJlZCBmb3IgcGxvdHRpbmcNCmxpYnJhcnkoZWZmZWN0c2l6ZSkgI1JlcXVpcmVkIGZvciBldGFfc3F1YXJlZCBlZmZlY3Qgc2l6ZXMNCmxpYnJhcnkoZW1tZWFucykgI1JlcXVpcmVkIGZvciBwYWlyd2lzZSBjb21wYXJpc29ucw0KbGlicmFyeShkcGx5cikgI1JlcXVpcmVkIHRvIHNlcGVyYXRlIGNvbHVtbnMgaW4gZGF0YWZyYW1lDQpsaWJyYXJ5KHRpZHlyKSAjUmVxdWlyZWQgZm9yIGRhdGEgb3JnYW5pemF0aW9uDQpsaWJyYXJ5KFJtaXNjKSAjUmVxdWlyZWQgZm9yIHN1bW1hcnlTRSBmb3Igc3VtbWFyeSBzdGF0aXN0aWNzDQpsaWJyYXJ5KGdncHVicikgI1JlcXVpcmVkIGZvciBhZGRpbmcgcGFpcndpc2UgcC12YWx1ZXMgdG8gcGxvdHMgd2l0aCBzdGF0X3B2YWx1ZV9tYW51YWwgDQpsaWJyYXJ5KGNvd3Bsb3QpICNSZXF1aXJlZCBmb3IgYXJyYW5naW5nIGdncGxvdHMgDQpsaWJyYXJ5KGdyaWRHcmFwaGljcykgI1JlcXVpcmVkIGZvciBhZGRpbmcgbGFiZWxzIHRvIGFycmFuZ2VkIHBsb3RzDQpsaWJyYXJ5KHRpZHlyKSAjUmVxdWlyZWQgZm9yIHJlc2hhcGluZyBkYXRhZnJvbSBmcm9tIGEgd2lkZSB0byBsb25nIGZvcm1hdC4NCmBgYA0KTm90ZTogUnVuICJHcmFwaGluZyBQYXJhbWV0ZXJzIiBzZWN0aW9uIGZyb20gMDFfRXhwZXJpbWVudGFsU2V0dXAuUiBmaWxlDQoNCg0KIyMjIExvYWQgYW5kIE9yZ2FuaXplIERhdGENCk5vdGU6IEZ1bGwgRGF0YSB3aXRoIEJsZWFjaGluZyBNZXRyaWNzIGFuZCBDb2xvciBTY29yZXMgY3JlYXRlZCBpbiAwNF9Nb2RlbHMuUiBmaWxlDQpgYGB7cn0NCiNMb2FkIERhdGENCkZ1bGxEYXRhPC1yZWFkLmNzdigiT3V0cHV0cy9GdWxsRGF0YS5jc3YiLCBoZWFkZXI9VFJVRSkNCg0KDQojU2V0IGZhY3RvciB2YXJpYWJsZXMgDQpGdWxsRGF0YSRUaW1lUDwtZmFjdG9yKEZ1bGxEYXRhJFRpbWVQLCBsZXZlbHM9YygiVzIiLCAiTTEiLCAiTTQiKSwgb3JkZXJlZD1UUlVFKQ0KRnVsbERhdGEkU2l0ZTwtZmFjdG9yKEZ1bGxEYXRhJFNpdGUsIGxldmVscz1jKCJLTCIsICJTUyIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRHZW5vdHlwZTwtZmFjdG9yKEZ1bGxEYXRhJEdlbm90eXBlLCBsZXZlbHM9YygiQUMxMCIsICJBQzEyIiwgIkFDOCIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRUcmVhdG1lbnQ8LWZhY3RvcihGdWxsRGF0YSRUcmVhdG1lbnQsIGxldmVscz1jKCJDb250cm9sIiwgIkhlYXQiKSwgb3JkZXJlZD1UUlVFKQ0KRnVsbERhdGEkVHJlYXQ8LWZhY3RvcihGdWxsRGF0YSRUcmVhdCwgbGV2ZWxzPWMoIkMiLCAiSCIpLCBvcmRlcmVkPVRSVUUpDQpGdWxsRGF0YSRTZWFzPC1mYWN0b3IoRnVsbERhdGEkU2VhcywgbGV2ZWxzPWMoIlN1bW1lcjEiLCAiU3VtbWVyMiIsICJXaW50ZXIiKSwgb3JkZXJlZD1UUlVFKQ0KYGBgDQoNCg0KIyBQZXJjZW50IFJldGVudGlvbg0KDQojIyMgU3Vic2V0IFRoZXJtYWwgQXNzYXkgRGF0YSBieSBUcmVhdG1lbnQNCmBgYHtyfQ0KIyNDb250cm9sDQpGdWxsRGF0YV9DPC1zdWJzZXQoRnVsbERhdGEsIFRyZWF0PT0iQyIpDQoNCiMjSGVhdGVkDQpGdWxsRGF0YV9IPC1zdWJzZXQoRnVsbERhdGEsIFRyZWF0PT0iSCIpDQpgYGANCg0KDQojIyMgQ2FsY3VsYXRlIFBlcmNlbnQgUmV0ZW50aW9uDQpDYWxjdWxhdGluZyByZXRlbnRpb24gYXMgcHJvcG9ydGlvbiByZW1haW5pbmcgcmVsYXRpdmUgdG8gY29ycmVzcG9uZGluZyBjb250cm9sIGxldmVscyAoMC0xKSBmb3IgZWFjaCBzaXRlIGFuZCBnZW5vdHlwZSBhdCBlYWNoIHRpbWVwb2ludC4NCmBgYHtyfQ0KIyNDYWxjdWxhdGUgYXZlcmFnZXMgZm9yIENvbnRyb2wgVHJlYXRtZW50IGZvciBlYWNoIFNpdGUsIEdlbm90eXBlLCBUaW1lcG9pbnQsIGFuZCBTZWFzb24NCm5hbWVzKEZ1bGxEYXRhX0MpDQpGdWxsRGF0YV9DLmE8LWFnZ3JlZ2F0ZShGdWxsRGF0YV9DWyxjKDk6MTAsIDEzOjE0KV0sIGxpc3QoRnVsbERhdGFfQyRTaXRlLCBGdWxsRGF0YV9DJEdlbm90eXBlLCBGdWxsRGF0YV9DJFRpbWVQLCBGdWxsRGF0YV9DJFNlYXMpLCBtZWFuLCBuYS5hY3Rpb24gPSBuYS5vbWl0KQ0KbmFtZXMoRnVsbERhdGFfQy5hKVsxOjRdPC1jKCJTaXRlIiwgIkdlbm90eXBlIiwgIlRpbWVQIiwgIlNlYXMiKQ0KbmFtZXMoRnVsbERhdGFfQy5hKVs1OjhdPC1wYXN0ZShuYW1lcyhGdWxsRGF0YV9DKVtjKDk6MTAsIDEzOjE0KV0sICJDIiwgc2VwPSJfIikNCg0KIyNNZXJnZSBDb250cm9sIEF2ZXJhZ2VzIHdpdGggSGVhdGVkIFNhbXBsZXMNCiNNZXJnZXMgYnkgU2l0ZSwgR2Vub3R5cGUsIFRpbWVwb2ludCwgYW5kIFNlYXNvbg0KVG9sRGF0YTwtbWVyZ2UoRnVsbERhdGFfSCwgRnVsbERhdGFfQy5hLCBhbGwueD1UUlVFICkNCg0KIyNDYWxjdWxhdGUgUHJvcG9ydGlvbiBSZXRhaW5lZCBmb3IgZWFjaCBCbGVhY2hpbmcgTWV0cmljIHJlbGF0aXZlIHRvIENvbnRyb2wNClRvbERhdGEkU2NvcmVfRnVsbC5wcm9wPC1yb3VuZCgoVG9sRGF0YSRTY29yZV9GdWxsL1RvbERhdGEkU2NvcmVfRnVsbF9DKSwgNCkNClRvbERhdGEkU2NvcmVfVFAucHJvcDwtcm91bmQoKFRvbERhdGEkU2NvcmVfVFAvVG9sRGF0YSRTY29yZV9UUF9DKSwgNCkNClRvbERhdGEkQ2hsLnByb3A8LXJvdW5kKChUb2xEYXRhJENobF91Zy5jbTIvVG9sRGF0YSRDaGxfdWcuY20yX0MpLCA0KQ0KVG9sRGF0YSRTeW0ucHJvcDwtcm91bmQoKFRvbERhdGEkU3ltMTAuNl9jbTIvVG9sRGF0YSRTeW0xMC42X2NtMl9DKSwgNCkNCg0KIyNTZXQgdmFsdWVzID4xIHRvIDENClRvbERhdGEkU2NvcmVfRnVsbC5wcm9wW3doaWNoKFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wPjEpXTwtMS4wMDAwDQpUb2xEYXRhJFNjb3JlX1RQLnByb3Bbd2hpY2goVG9sRGF0YSRTY29yZV9UUC5wcm9wPjEpXTwtMS4wMDAwDQpUb2xEYXRhJENobC5wcm9wW3doaWNoKFRvbERhdGEkQ2hsLnByb3A+MSldPC0xLjAwMDANClRvbERhdGEkU3ltLnByb3Bbd2hpY2goVG9sRGF0YSRTeW0ucHJvcD4xKV08LTEuMDAwMA0KDQojI0NyZWF0ZSBTaXRlIGFuZCBHZW5vdHlwZSBWYXJpYWJsZQ0KVG9sRGF0YSRTaXRlLkdlbm88LXBhc3RlKFRvbERhdGEkU2l0ZSwgVG9sRGF0YSRHZW5vdHlwZSwgc2VwPSJfIikNCmBgYA0KDQoNCiMjIyBTdWJzZXQgYnkgVGltZXBvaW50DQpgYGB7cn0NClRvbERhdGFfVzI8LXN1YnNldChUb2xEYXRhLCBUaW1lUD09IlcyIikNClRvbERhdGFfTTE8LXN1YnNldChUb2xEYXRhLCBUaW1lUD09Ik0xIikNClRvbERhdGFfTTQ8LXN1YnNldChUb2xEYXRhLCBUaW1lUD09Ik00IikNCmBgYA0KDQoNCg0KIyBUaGVybWFsIFRvbGVyYW5jZSBDaGxvcm9waHlsbA0KDQojIyBGdWxsIFNldA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGEkQ2hsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YSRDaGwucHJvcCkNCiNOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlIGFuZCBUaW1lcG9pbnQNClRvbF9DaGxfbG08LWxtKENobC5wcm9wflNpdGUrR2Vub3R5cGUrVGltZVArIFNpdGU6R2Vub3R5cGUgKyBTaXRlOlRpbWVQICsgR2Vub3R5cGU6VGltZVAsIGRhdGE9VG9sRGF0YSkNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9DaGxfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX0NobF9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX0NobF9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfQ2hsX2xtKSwgcmVzaWQoVG9sX0NobF9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX0NobF9sbSkNCmFub3ZhKFRvbF9DaGxfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfQ2hsX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX0NobF9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX0NobF9sbSkpDQpUb2xfQ2hsX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9DaGxfbG0ucmVzKQ0KVG9sX0NobF9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX0NobF9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfQ2hsX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCIsIG5yb3coVG9sX0NobF9sbS5yZXMpKQ0KVG9sX0NobF9sbS5yZXM8LVRvbF9DaGxfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANClN0cm9uZyBpbmZsdWVuY2Ugb2YgVGltZXBvaW50LCBpbmNsdWRpbmcgaW50ZXJhY3Rpb25zIHdpdGggbWFpbiB2YXJpYWJsZXMgb2YgaW50ZXJlc3QsIFNpdGUgYW5kIEdlbm90eXBlLiBXaWxsIGFuYWx5emUgZWFjaCBUaW1lcG9pbnQgaW5kaXZpZHVhbGx5LiANCg0KDQojIyBDaGwgU3VtbWVyIDEgVGltZXBvaW50IFcyIA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfVzIkQ2hsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9XMiRDaGwucHJvcCkNCiNOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfQ2hsX1cyX2xtPC1sbShDaGwucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9XMikNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9DaGxfVzJfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX0NobF9XMl9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX0NobF9XMl9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfQ2hsX1cyX2xtKSwgcmVzaWQoVG9sX0NobF9XMl9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfQ2hsX1cyX2xtKQ0KYW5vdmEoVG9sX0NobF9XMl9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9DaGxfVzJfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfQ2hsX1cyX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfQ2hsX1cyX2xtKSkNClRvbF9DaGxfVzJfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX0NobF9XMl9sbS5yZXMpDQpUb2xfQ2hsX1cyX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfQ2hsX1cyX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9DaGxfVzJfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX1cyX2xtLnJlcykpDQpUb2xfQ2hsX1cyX2xtLnJlcyRUaW1lUDwtcmVwKCJXMiIsIG5yb3coVG9sX0NobF9XMl9sbS5yZXMpKQ0KVG9sX0NobF9XMl9sbS5yZXM8LVRvbF9DaGxfVzJfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX0NobF9XMl9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KZW1tZWFucyhUb2xfQ2hsX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX0NobF9XMl9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX0NobF9XMl9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKSRjb250cmFzdHMpDQpUb2xfQ2hsX1cyX2xtLmdlbm88LVRvbF9DaGxfVzJfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9DaGxfVzJfbG0uZ2VubyRncm91cDE8LXBhc3RlKFRvbF9DaGxfVzJfbG0uZ2VubyRTaXRlLCBUb2xfQ2hsX1cyX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX0NobF9XMl9sbS5nZW5vJGdyb3VwMjwtcGFzdGUoVG9sX0NobF9XMl9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfVzJfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfQ2hsX1cyX2xtLnNpdGU8LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX1cyX2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9DaGxfVzJfbG0uc2l0ZTwtVG9sX0NobF9XMl9sbS5zaXRlICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9XMl9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9XMl9sbS5zaXRlJGdyb3VwMSwgVG9sX0NobF9XMl9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KVG9sX0NobF9XMl9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX0NobF9XMl9sbS5zaXRlJGdyb3VwMiwgVG9sX0NobF9XMl9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KDQojRnVsbCBsaXN0IG9mIHAtdmFsdWVzDQpUb2xfQ2hsX1cyX2xtLnA8LXJiaW5kKFRvbF9DaGxfVzJfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9DaGxfVzJfbG0uc2l0ZVssYygxOjIsNDo4KV0pDQpUb2xfQ2hsX1cyX2xtLnA8LVRvbF9DaGxfVzJfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX0NobF9XMl9sbS5wJFNpZzwtaWZlbHNlKFRvbF9DaGxfVzJfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9DaGxfVzJfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfQ2hsX1cyX2xtLnAkcDwwLjA1LCAiKiIsIE5BKSkpDQoNCiNTcGVjaWZ5IFJlc3BvbnNlIGFuZCBUaW1lcG9pbnQNClRvbF9DaGxfVzJfbG0ucCRSZXNwb25zZTwtcmVwKCJDaGxvcm9waHlsbCIsIG5yb3coVG9sX0NobF9XMl9sbS5wKSkNClRvbF9DaGxfVzJfbG0ucCRUaW1lUDwtcmVwKCJXMiIsIG5yb3coVG9sX0NobF9XMl9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfQ2hsX1cyX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9XMiwgbWVhc3VyZXZhcj0iQ2hsLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfQ2hsX1cyX1NHLnBsb3Q8LWdncGxvdChUb2xfQ2hsX1cyX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9Q2hsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49Q2hsLnByb3Atc2UsIHltYXg9Q2hsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBDaGxvcm9waHlsbCBSZXRhaW5lZCIpKw0KICB5bGltKDAsIDEpKyANCiAgc2NhbGVfeF9kaXNjcmV0ZShsYWJlbHM9YygiIiwiS2xlaW4iLCIiLCIiLCJTb21ldGhpbmcgU3BlY2lhbCIsIiIpKSsNCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IEdlbm8uY29sb3JzLm8pKyANCiAgc3RhdF9wdmFsdWVfbWFudWFsKGRhdGE9VG9sX0NobF9XMl9sbS5wLCAgeS5wb3NpdGlvbj0wLjQsIHN0ZXAuaW5jcmVhc2U9MC4yNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9DaGxfVzJfU0cucGxvdA0KDQpgYGANCg0KDQojIyBDaGwgU3VtbWVyIDIgVGltZXBvaW50IE0xDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NMSRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX00xJENobC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfTTFfbG08LWxtKENobC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX00xKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9NMV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX00xX2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX00xX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfTTFfbG0pLCByZXNpZChUb2xfQ2hsX00xX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGxfTTFfbG0pDQphbm92YShUb2xfQ2hsX00xX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX0NobF9NMV9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9DaGxfTTFfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9DaGxfTTFfbG0pKQ0KVG9sX0NobF9NMV9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfQ2hsX00xX2xtLnJlcykNClRvbF9DaGxfTTFfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGxfTTFfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX0NobF9NMV9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ2hsb3JvcGh5bGwiLCBucm93KFRvbF9DaGxfTTFfbG0ucmVzKSkNClRvbF9DaGxfTTFfbG0ucmVzJFRpbWVQPC1yZXAoIk0xIiwgbnJvdyhUb2xfQ2hsX00xX2xtLnJlcykpDQpUb2xfQ2hsX00xX2xtLnJlczwtVG9sX0NobF9NMV9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfQ2hsX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9DaGxfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfQ2hsX00xX2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9DaGxfTTFfbG0uZ2VubzwtVG9sX0NobF9NMV9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9NMV9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9NMV9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfTTFfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfQ2hsX00xX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX00xX2xtLmdlbm8kU2l0ZSwgVG9sX0NobF9NMV9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9DaGxfTTFfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9DaGxfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX0NobF9NMV9sbS5zaXRlPC1Ub2xfQ2hsX00xX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfQ2hsX00xX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfQ2hsX00xX2xtLnNpdGUkZ3JvdXAxLCBUb2xfQ2hsX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfQ2hsX00xX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX00xX2xtLnNpdGUkZ3JvdXAyLCBUb2xfQ2hsX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9DaGxfTTFfbG0ucDwtcmJpbmQoVG9sX0NobF9NMV9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX0NobF9NMV9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9DaGxfTTFfbG0ucDwtVG9sX0NobF9NMV9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfQ2hsX00xX2xtLnAkU2lnPC1pZmVsc2UoVG9sX0NobF9NMV9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX0NobF9NMV9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9DaGxfTTFfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9NMV9sbS5wJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX00xX2xtLnApKQ0KVG9sX0NobF9NMV9sbS5wJFRpbWVQPC1yZXAoIk0xIiwgbnJvdyhUb2xfQ2hsX00xX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfTTFfU0c8LXN1bW1hcnlTRShUb2xEYXRhX00xLCBtZWFzdXJldmFyPSJDaGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9DaGxfTTFfU0cucGxvdDwtZ2dwbG90KFRvbF9DaGxfTTFfU0csIGFlcyh4PVNpdGUuR2VubywgeT1DaGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIENobG9yb3BoeWxsIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfQ2hsX00xX2xtLnAsICB5LnBvc2l0aW9uPTAuNCwgc3RlcC5pbmNyZWFzZT0wLjI1LCBsYWJlbD0iU2lnIiwgaGlkZS5ucz1UUlVFKTsgVG9sX0NobF9NMV9TRy5wbG90DQoNCmBgYA0KDQoNCiMjIENobCBXaW50ZXIgVGltZXBvaW50IE00DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NNCRDaGwucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX000JENobC5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGFfTTQkQ2hsLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGFfTTQkQ2hsLnByb3ArMSkpDQojTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KIyNNb2RlbCB3aXRoIGxvZyB0cmFuc2Zvcm1hdGlvbg0KVG9sX0NobF9NNF9sbTwtbG0obG9nKENobC5wcm9wKzEpflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX0NobF9NNF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfQ2hsX000X2xtKSk7IHFxbGluZShyZXNpZChUb2xfQ2hsX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9DaGxfTTRfbG0pLCByZXNpZChUb2xfQ2hsX000X2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9DaGxfTTRfbG0pDQphbm92YShUb2xfQ2hsX000X2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX0NobF9NNF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9DaGxfTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9DaGxfTTRfbG0pKQ0KVG9sX0NobF9NNF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfQ2hsX000X2xtLnJlcykNClRvbF9DaGxfTTRfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9DaGxfTTRfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX0NobF9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ2hsb3JvcGh5bGwiLCBucm93KFRvbF9DaGxfTTRfbG0ucmVzKSkNClRvbF9DaGxfTTRfbG0ucmVzJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfQ2hsX000X2xtLnJlcykpDQpUb2xfQ2hsX000X2xtLnJlczwtVG9sX0NobF9NNF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUgYW5kIFNpdGUqR2Vub3R5cGUuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfQ2hsX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9DaGxfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfQ2hsX000X2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfQ2hsX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9DaGxfTTRfbG0uZ2VubzwtVG9sX0NobF9NNF9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX0NobF9NNF9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX0NobF9NNF9sbS5nZW5vJFNpdGUsIFRvbF9DaGxfTTRfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfQ2hsX000X2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX000X2xtLmdlbm8kU2l0ZSwgVG9sX0NobF9NNF9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9DaGxfTTRfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9DaGxfTTRfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX0NobF9NNF9sbS5zaXRlPC1Ub2xfQ2hsX000X2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAxLCBUb2xfQ2hsX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfQ2hsX000X2xtLnNpdGUkZ3JvdXAyLCBUb2xfQ2hsX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9DaGxfTTRfbG0ucDwtcmJpbmQoVG9sX0NobF9NNF9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX0NobF9NNF9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9DaGxfTTRfbG0ucDwtVG9sX0NobF9NNF9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfQ2hsX000X2xtLnAkU2lnPC1pZmVsc2UoVG9sX0NobF9NNF9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX0NobF9NNF9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9DaGxfTTRfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX0NobF9NNF9sbS5wJFJlc3BvbnNlPC1yZXAoIkNobG9yb3BoeWxsIiwgbnJvdyhUb2xfQ2hsX000X2xtLnApKQ0KVG9sX0NobF9NNF9sbS5wJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfQ2hsX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9DaGxfTTRfU0c8LXN1bW1hcnlTRShUb2xEYXRhX000LCBtZWFzdXJldmFyPSJDaGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9DaGxfTTRfU0cucGxvdDwtZ2dwbG90KFRvbF9DaGxfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1DaGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1DaGwucHJvcC1zZSwgeW1heD1DaGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIENobG9yb3BoeWxsIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfQ2hsX000X2xtLnAsICB5LnBvc2l0aW9uPTAuNTUsIHN0ZXAuaW5jcmVhc2U9MC4yMCwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9DaGxfTTRfU0cucGxvdA0KDQpgYGANCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIFN5bWJpb250cw0KDQojIyBGdWxsIFNldA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGEkU3ltLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YSRTeW0ucHJvcCkNCiNOb3QgTm9ybWFsDQoNCiMjVHJ5IGxvZysxIHRyYW5zZm9ybWF0aW9uDQpoaXN0KGxvZyhUb2xEYXRhJFN5bS5wcm9wKzEpKQ0Kc2hhcGlyby50ZXN0KGxvZyhUb2xEYXRhJFN5bS5wcm9wKzEpKQ0KI05vdCBub3JtYWwgDQoNCiMjVHJ5IHNxdWFyZSB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YSRTeW0ucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YSRTeW0ucHJvcCleMikNCiNOb3Qgbm9ybWFsIA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YSRTeW0ucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YSRTeW0ucHJvcCleMykNCiNOb3Qgbm9ybWFsIA0KDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZSBhbmQgVGltZXBvaW50DQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1N5bV9sbTwtbG0oU3ltLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1N5bV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU3ltX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU3ltX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TeW1fbG0pLCByZXNpZChUb2xfU3ltX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfU3ltX2xtKQ0KYW5vdmEoVG9sX1N5bV9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9TeW1fbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfU3ltX2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU3ltX2xtKSkNClRvbF9TeW1fbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX1N5bV9sbS5yZXMpDQpUb2xfU3ltX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU3ltX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9TeW1fbG0ucmVzJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250cyIsIG5yb3coVG9sX1N5bV9sbS5yZXMpKQ0KVG9sX1N5bV9sbS5yZXM8LVRvbF9TeW1fbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANClN0cm9uZyBpbmZsdWVuY2Ugb2YgVGltZXBvaW50LCBpbmNsdWRpbmcgaW50ZXJhY3Rpb25zIHdpdGggbWFpbiB2YXJpYWJsZXMgb2YgaW50ZXJlc3QsIFNpdGUgYW5kIEdlbm90eXBlLiBXaWxsIGFuYWx5emUgZWFjaCBUaW1lcG9pbnQgaW5kaXZpZHVhbGx5LiANCg0KDQojIyBTeW0gU3VtbWVyIDEgVGltZXBvaW50IFcyDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9XMiRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX1cyJFN5bS5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TeW1fVzJfbG08LWxtKFN5bS5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX1cyKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1N5bV9XMl9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU3ltX1cyX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU3ltX1cyX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TeW1fVzJfbG0pLCByZXNpZChUb2xfU3ltX1cyX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TeW1fVzJfbG0pDQphbm92YShUb2xfU3ltX1cyX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1N5bV9XMl9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TeW1fVzJfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TeW1fVzJfbG0pKQ0KVG9sX1N5bV9XMl9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU3ltX1cyX2xtLnJlcykNClRvbF9TeW1fVzJfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TeW1fVzJfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1N5bV9XMl9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX1cyX2xtLnJlcykpDQpUb2xfU3ltX1cyX2xtLnJlcyRUaW1lUDwtcmVwKCJXMiIsIG5yb3coVG9sX1N5bV9XMl9sbS5yZXMpKQ0KVG9sX1N5bV9XMl9sbS5yZXM8LVRvbF9TeW1fVzJfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBNYXJnaW5hbCBlZmZlY3QgKHA8MC4xKSBvZiBTaXRlICogR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TeW1fVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1N5bV9XMl9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TeW1fVzJfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TeW1fVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1N5bV9XMl9sbS5nZW5vPC1Ub2xfU3ltX1cyX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU3ltX1cyX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU3ltX1cyX2xtLmdlbm8kU2l0ZSwgVG9sX1N5bV9XMl9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TeW1fVzJfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TeW1fVzJfbG0uZ2VubyRTaXRlLCBUb2xfU3ltX1cyX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1N5bV9XMl9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1N5bV9XMl9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU3ltX1cyX2xtLnNpdGU8LVRvbF9TeW1fVzJfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TeW1fVzJfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TeW1fVzJfbG0uc2l0ZSRncm91cDEsIFRvbF9TeW1fVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TeW1fVzJfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TeW1fVzJfbG0uc2l0ZSRncm91cDIsIFRvbF9TeW1fVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1N5bV9XMl9sbS5wPC1yYmluZChUb2xfU3ltX1cyX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU3ltX1cyX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1N5bV9XMl9sbS5wPC1Ub2xfU3ltX1cyX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TeW1fVzJfbG0ucCRTaWc8LWlmZWxzZShUb2xfU3ltX1cyX2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU3ltX1cyX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1N5bV9XMl9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU3ltX1cyX2xtLnAkUmVzcG9uc2U8LXJlcCgiU3ltYmlvbnRzIiwgbnJvdyhUb2xfU3ltX1cyX2xtLnApKQ0KVG9sX1N5bV9XMl9sbS5wJFRpbWVQPC1yZXAoIlcyIiwgbnJvdyhUb2xfU3ltX1cyX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TeW1fVzJfU0c8LXN1bW1hcnlTRShUb2xEYXRhX1cyLCBtZWFzdXJldmFyPSJTeW0ucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TeW1fVzJfU0cucGxvdDwtZ2dwbG90KFRvbF9TeW1fVzJfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TeW0ucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TeW0ucHJvcC1zZSwgeW1heD1TeW0ucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIFN5bWJpb250cyBSZXRhaW5lZCIpKw0KICB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU3ltX1cyX2xtLnAsICB5LnBvc2l0aW9uPTAuOTUsIHN0ZXAuaW5jcmVhc2U9MC4xNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TeW1fVzJfU0cucGxvdA0KDQpgYGANCg0KDQojIyBTeW0gU3VtbWVyIDIgVGltZXBvaW50IE0xDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NMSRTeW0ucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX00xJFN5bS5wcm9wKQ0KI05vdCBub3JtYWwNCg0KIyNUcnkgbG9nKzEgdHJhbnNmb3JtYXRpb24NCmhpc3QobG9nKFRvbERhdGFfTTEkU3ltLnByb3ArMSkpDQpzaGFwaXJvLnRlc3QobG9nKFRvbERhdGFfTTEkU3ltLnByb3ArMSkpDQojTm90IG5vcm1hbCBidXQgaW1wcm92ZWQNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbG9nIHRyYW5zZm9ybWF0aW9uDQpUb2xfU3ltX00xX2xtPC1sbShsb2coU3ltLnByb3ArMSl+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX00xX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fTTFfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fTTFfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9NMV9sbSksIHJlc2lkKFRvbF9TeW1fTTFfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1N5bV9NMV9sbSkNCmFub3ZhKFRvbF9TeW1fTTFfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU3ltX00xX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9NMV9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1N5bV9NMV9sbSkpDQpUb2xfU3ltX00xX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TeW1fTTFfbG0ucmVzKQ0KVG9sX1N5bV9NMV9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bV9NMV9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU3ltX00xX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fTTFfbG0ucmVzKSkNClRvbF9TeW1fTTFfbG0ucmVzJFRpbWVQPC1yZXAoIk0xIiwgbnJvdyhUb2xfU3ltX00xX2xtLnJlcykpDQpUb2xfU3ltX00xX2xtLnJlczwtVG9sX1N5bV9NMV9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfU3ltX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TeW1fTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU3ltX00xX2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU3ltX00xX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TeW1fTTFfbG0uZ2VubzwtVG9sX1N5bV9NMV9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1N5bV9NMV9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1N5bV9NMV9sbS5nZW5vJFNpdGUsIFRvbF9TeW1fTTFfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfU3ltX00xX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU3ltX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1N5bV9NMV9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9TeW1fTTFfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TeW1fTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1N5bV9NMV9sbS5zaXRlPC1Ub2xfU3ltX00xX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAxLCBUb2xfU3ltX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU3ltX00xX2xtLnNpdGUkZ3JvdXAyLCBUb2xfU3ltX00xX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TeW1fTTFfbG0ucDwtcmJpbmQoVG9sX1N5bV9NMV9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX1N5bV9NMV9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TeW1fTTFfbG0ucDwtVG9sX1N5bV9NMV9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfU3ltX00xX2xtLnAkU2lnPC1pZmVsc2UoVG9sX1N5bV9NMV9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1N5bV9NMV9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9TeW1fTTFfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1N5bV9NMV9sbS5wJFJlc3BvbnNlPC1yZXAoIlN5bWJpb250cyIsIG5yb3coVG9sX1N5bV9NMV9sbS5wKSkNClRvbF9TeW1fTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1N5bV9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU3ltX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU3ltLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfU3ltX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfU3ltX00xX1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9U3ltLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U3ltLnByb3Atc2UsIHltYXg9U3ltLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBTeW1iaW9udHMgUmV0YWluZWQiKSsNCiB5bGltKDAsIDEuNSkrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU3ltX00xX2xtLnAsICB5LnBvc2l0aW9uPTAuOTUsIHN0ZXAuaW5jcmVhc2U9MC4xNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TeW1fTTFfU0cucGxvdA0KDQpgYGANCg0KDQojIyBTeW0gV2ludGVyIFRpbWVwb2ludCBNNA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTQkU3ltLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NNCRTeW0ucHJvcCkNCiNOb3QgTm9ybWFsDQoNCiMjVHJ5IHNxdWFyZSB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YV9NNCRTeW0ucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NNCRTeW0ucHJvcCleMikNCiNOb3QgTm9ybWFsDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFN5bS5wcm9wKV4zKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhX000JFN5bS5wcm9wKV4zKQ0KI05vdCBOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1N5bV9NNF9sbTwtbG0oU3ltLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTQpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU3ltX000X2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TeW1fTTRfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TeW1fTTRfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1N5bV9NNF9sbSksIHJlc2lkKFRvbF9TeW1fTTRfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1N5bV9NNF9sbSkNCmFub3ZhKFRvbF9TeW1fTTRfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU3ltX000X2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1N5bV9NNF9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1N5bV9NNF9sbSkpDQpUb2xfU3ltX000X2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TeW1fTTRfbG0ucmVzKQ0KVG9sX1N5bV9NNF9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1N5bV9NNF9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU3ltX000X2xtLnJlcyRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fTTRfbG0ucmVzKSkNClRvbF9TeW1fTTRfbG0ucmVzJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfU3ltX000X2xtLnJlcykpDQpUb2xfU3ltX000X2xtLnJlczwtVG9sX1N5bV9NNF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgU2l0ZSBhbmQgR2Vub3R5cGUuIE1hcmdpbmFsIGVmZmVjdCAocDwwLjEpIG9mIFNpdGUgKiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1N5bV9NNF9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KZW1tZWFucyhUb2xfU3ltX000X2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX1N5bV9NNF9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1N5bV9NNF9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKSRjb250cmFzdHMpDQpUb2xfU3ltX000X2xtLmdlbm88LVRvbF9TeW1fTTRfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TeW1fTTRfbG0uZ2VubyRncm91cDE8LXBhc3RlKFRvbF9TeW1fTTRfbG0uZ2VubyRTaXRlLCBUb2xfU3ltX000X2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1N5bV9NNF9sbS5nZW5vJGdyb3VwMjwtcGFzdGUoVG9sX1N5bV9NNF9sbS5nZW5vJFNpdGUsIFRvbF9TeW1fTTRfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU3ltX000X2xtLnNpdGU8LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU3ltX000X2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9TeW1fTTRfbG0uc2l0ZTwtVG9sX1N5bV9NNF9sbS5zaXRlICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1N5bV9NNF9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX1N5bV9NNF9sbS5zaXRlJGdyb3VwMSwgVG9sX1N5bV9NNF9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KVG9sX1N5bV9NNF9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX1N5bV9NNF9sbS5zaXRlJGdyb3VwMiwgVG9sX1N5bV9NNF9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KDQojRnVsbCBsaXN0IG9mIHAtdmFsdWVzDQpUb2xfU3ltX000X2xtLnA8LXJiaW5kKFRvbF9TeW1fTTRfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TeW1fTTRfbG0uc2l0ZVssYygxOjIsNDo4KV0pDQpUb2xfU3ltX000X2xtLnA8LVRvbF9TeW1fTTRfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1N5bV9NNF9sbS5wJFNpZzwtaWZlbHNlKFRvbF9TeW1fTTRfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9TeW1fTTRfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU3ltX000X2xtLnAkcDwwLjA1LCAiKiIsIE5BKSkpDQoNCiNTcGVjaWZ5IFJlc3BvbnNlIGFuZCBUaW1lcG9pbnQNClRvbF9TeW1fTTRfbG0ucCRSZXNwb25zZTwtcmVwKCJTeW1iaW9udHMiLCBucm93KFRvbF9TeW1fTTRfbG0ucCkpDQpUb2xfU3ltX000X2xtLnAkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TeW1fTTRfbG0ucCkpDQoNCmBgYA0KDQoNCiMjIyBQbG90IFJldGVudGlvbiBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1N5bV9NNF9TRzwtc3VtbWFyeVNFKFRvbERhdGFfTTQsIG1lYXN1cmV2YXI9IlN5bS5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1N5bV9NNF9TRy5wbG90PC1nZ3Bsb3QoVG9sX1N5bV9NNF9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVN5bS5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVN5bS5wcm9wLXNlLCB5bWF4PVN5bS5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gU3ltYmlvbnRzIFJldGFpbmVkIikrDQogIHlsaW0oMCwgMS41KSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TeW1fTTRfbG0ucCwgIHkucG9zaXRpb249MS4xLCBzdGVwLmluY3JlYXNlPTAuMTUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfU3ltX000X1NHLnBsb3QNCg0KYGBgDQoNCg0KIyBUaGVybWFsIFRvbGVyYW5jZSBDb2xvciBGdWxsIFNldA0KDQojIyBGdWxsIFNldA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFNjb3JlX0Z1bGwucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YSRTY29yZV9GdWxsLnByb3ApXjIpDQojTm90IG5vcm1hbCANCg0KIyNUcnkgY3ViZWQgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGEkU2NvcmVfRnVsbC5wcm9wKV4zKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhJFNjb3JlX0Z1bGwucHJvcCleMykNCiNOb3Qgbm9ybWFsIA0KDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZSBhbmQgVGltZXBvaW50DQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlRl9sbTwtbG0oU2NvcmVfRnVsbC5wcm9wflNpdGUrR2Vub3R5cGUrVGltZVArIFNpdGU6R2Vub3R5cGUgKyBTaXRlOlRpbWVQICsgR2Vub3R5cGU6VGltZVAsIGRhdGE9VG9sRGF0YSkNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9TY29yZUZfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlRl9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX1Njb3JlRl9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfU2NvcmVGX2xtKSwgcmVzaWQoVG9sX1Njb3JlRl9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlRl9sbSkNCmFub3ZhKFRvbF9TY29yZUZfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVGX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlRl9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1Njb3JlRl9sbSkpDQpUb2xfU2NvcmVGX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZUZfbG0ucmVzKQ0KVG9sX1Njb3JlRl9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVGX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDb2xvcl9GdWxsU2V0IiwgbnJvdyhUb2xfU2NvcmVGX2xtLnJlcykpDQpUb2xfU2NvcmVGX2xtLnJlczwtVG9sX1Njb3JlRl9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KU3Ryb25nIGluZmx1ZW5jZSBvZiBUaW1lcG9pbnQsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgd2l0aCBHZW5vdHlwZS4gV2lsbCBhbmFseXplIGVhY2ggVGltZXBvaW50IGluZGl2aWR1YWxseS4gDQoNCg0KIyMgQ29sb3IgU2NvcmUgRnVsbCBTZXQgU3VtbWVyIDEgVGltZXBvaW50IFcyDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9XMiRTY29yZV9GdWxsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9XMiRTY29yZV9GdWxsLnByb3ApDQojTm90IG5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGFfVzIkU2NvcmVfRnVsbC5wcm9wKV4yKQ0Kc2hhcGlyby50ZXN0KChUb2xEYXRhX1cyJFNjb3JlX0Z1bGwucHJvcCleMikNCiNOb3Qgbm9ybWFsDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX1cyJFNjb3JlX0Z1bGwucHJvcCleMykNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9XMiRTY29yZV9GdWxsLnByb3ApXjMpDQojTm90IG5vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNCiMjTW9kZWwgd2l0aCBubyB0cmFuc2Zvcm1hdGlvbiBhbmQgY2hlY2sgcmVzaWR1YWxzDQpUb2xfU2NvcmVGX1cyX2xtPC1sbShTY29yZV9GdWxsLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfVzIpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU2NvcmVGX1cyX2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TY29yZUZfVzJfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZUZfVzJfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1Njb3JlRl9XMl9sbSksIHJlc2lkKFRvbF9TY29yZUZfVzJfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlRl9XMl9sbSkNCmFub3ZhKFRvbF9TY29yZUZfVzJfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVGX1cyX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlRl9XMl9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1Njb3JlRl9XMl9sbSkpDQpUb2xfU2NvcmVGX1cyX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZUZfVzJfbG0ucmVzKQ0KVG9sX1Njb3JlRl9XMl9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9XMl9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVGX1cyX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDb2xvcl9GdWxsU2V0IiwgbnJvdyhUb2xfU2NvcmVGX1cyX2xtLnJlcykpDQpUb2xfU2NvcmVGX1cyX2xtLnJlcyRUaW1lUDwtcmVwKCJXMiIsIG5yb3coVG9sX1Njb3JlRl9XMl9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9XMl9sbS5yZXM8LVRvbF9TY29yZUZfVzJfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCg0KIyMjIyBQYWlyd2lzZQ0KYGBge3J9DQojUGFpcndpc2UgY29tcGFyaXNvbnMgYWNyb3NzOg0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KZW1tZWFucyhUb2xfU2NvcmVGX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TY29yZUZfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVGX1cyX2xtLmdlbm88LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU2NvcmVGX1cyX2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TY29yZUZfVzJfbG0uZ2VubzwtVG9sX1Njb3JlRl9XMl9sbS5nZW5vICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1Njb3JlRl9XMl9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlRl9XMl9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZUZfVzJfbG0uZ2VubyRncm91cDEsIHNlcD0iXyIpDQpUb2xfU2NvcmVGX1cyX2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVGX1cyX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9XMl9sbS5nZW5vJGdyb3VwMiwgc2VwPSJfIikNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNClRvbF9TY29yZUZfVzJfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9XMl9sbS5zaXRlPC1Ub2xfU2NvcmVGX1cyX2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX1cyX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX1cyX2xtLnNpdGUkZ3JvdXAxLCBUb2xfU2NvcmVGX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU2NvcmVGX1cyX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVGX1cyX2xtLnNpdGUkZ3JvdXAyLCBUb2xfU2NvcmVGX1cyX2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TY29yZUZfVzJfbG0ucDwtcmJpbmQoVG9sX1Njb3JlRl9XMl9sbS5nZW5vWyxjKDE6Miw0OjgpXSwgVG9sX1Njb3JlRl9XMl9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TY29yZUZfVzJfbG0ucDwtVG9sX1Njb3JlRl9XMl9sbS5wICU+JSBkcGx5cjo6cmVuYW1lKCBwID0gcC52YWx1ZSkNCg0KI0FkZCBTaWduaWZpY2FuY2UgTGV2ZWxzDQpUb2xfU2NvcmVGX1cyX2xtLnAkU2lnPC1pZmVsc2UoVG9sX1Njb3JlRl9XMl9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9XMl9sbS5wJHA8MC4wMSwgIioqIiwgaWZlbHNlKFRvbF9TY29yZUZfVzJfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1Njb3JlRl9XMl9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX0Z1bGxTZXQiLCBucm93KFRvbF9TY29yZUZfVzJfbG0ucCkpDQpUb2xfU2NvcmVGX1cyX2xtLnAkVGltZVA8LXJlcCgiVzIiLCBucm93KFRvbF9TY29yZUZfVzJfbG0ucCkpDQoNCmBgYA0KDQoNCiMjIyBQbG90IFJldGVudGlvbiBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KYGBge3J9DQojI1N1bW1hcnkgc3RhdGlzdGljcyBieSBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1Njb3JlRl9XMl9TRzwtc3VtbWFyeVNFKFRvbERhdGFfVzIsIG1lYXN1cmV2YXI9IlNjb3JlX0Z1bGwucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZUZfVzJfU0cucGxvdDwtZ2dwbG90KFRvbF9TY29yZUZfVzJfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9GdWxsLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfRnVsbC5wcm9wLXNlLCB5bWF4PVNjb3JlX0Z1bGwucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIENvbG9yIFJldGFpbmVkIChGdWxsKSIpKw0KICB5bGltKDAuNiwgMS4yKSsgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZUZfVzJfbG0ucCwgIHkucG9zaXRpb249MSwgc3RlcC5pbmNyZWFzZT0wLjMsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfU2NvcmVGX1cyX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ29sb3IgU2NvcmUgRnVsbCBTZXQgU3VtbWVyIDIgVGltZXBvaW50IE0xDQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NMSRTY29yZV9GdWxsLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9NMSRTY29yZV9GdWxsLnByb3ApDQojTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1Njb3JlRl9NMV9sbTwtbG0oU2NvcmVfRnVsbC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX00xKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlRl9NMV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVGX00xX2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVGX00xX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZUZfTTFfbG0pLCByZXNpZChUb2xfU2NvcmVGX00xX2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZUZfTTFfbG0pDQphbm92YShUb2xfU2NvcmVGX00xX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9NMV9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZUZfTTFfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZUZfTTFfbG0pKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVGX00xX2xtLnJlcykNClRvbF9TY29yZUZfTTFfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZUZfTTFfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9NMV9sbS5yZXMkVGltZVA8LXJlcCgiTTEiLCBucm93KFRvbF9TY29yZUZfTTFfbG0ucmVzKSkNClRvbF9TY29yZUZfTTFfbG0ucmVzPC1Ub2xfU2NvcmVGX00xX2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQoNClNpZ25pZmljYW50IGVmZmVjdCBvZiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZUZfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlRl9NMV9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKQ0KDQojI1NhdmUgcC12YWx1ZXMNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNClRvbF9TY29yZUZfTTFfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZUZfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlRl9NMV9sbS5nZW5vPC1Ub2xfU2NvcmVGX00xX2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVGX00xX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVGX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlRl9NMV9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZUZfTTFfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVGX00xX2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlRl9NMV9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlRl9NMV9sbSwgcGFpcndpc2V+U2l0ZSB8IEdlbm90eXBlKSRjb250cmFzdHMpDQpUb2xfU2NvcmVGX00xX2xtLnNpdGU8LVRvbF9TY29yZUZfTTFfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDE8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDI8LXBhc3RlKFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZUZfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlRl9NMV9sbS5wPC1yYmluZChUb2xfU2NvcmVGX00xX2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVGX00xX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlRl9NMV9sbS5wPC1Ub2xfU2NvcmVGX00xX2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZUZfTTFfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVGX00xX2xtLnAkcDwwLjAwMSwgIioqKiIsIGlmZWxzZShUb2xfU2NvcmVGX00xX2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlRl9NMV9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVGX00xX2xtLnAkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5wKSkNClRvbF9TY29yZUZfTTFfbG0ucCRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1Njb3JlRl9NMV9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVGX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU2NvcmVfRnVsbC5wcm9wIiwgZ3JvdXB2YXJzPWMoIlNpdGUuR2VubyIsICJTaXRlIiwgIkdlbm90eXBlIiksIG5hLnJtPVRSVUUpDQoNCiMjUGxvdCBBdmVyYWdlIFJldGVudGlvbiBhY3Jvc3MgVHJlYXRtZW50cw0KVG9sX1Njb3JlRl9NMV9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlRl9NMV9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX0Z1bGwucHJvcCwgY29sb3VyPUdlbm90eXBlKSkgKyANCiAgZ2VvbV9lcnJvcmJhcihhZXMoeW1pbj1TY29yZV9GdWxsLnByb3Atc2UsIHltYXg9U2NvcmVfRnVsbC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gQ29sb3IgUmV0YWluZWQgKEZ1bGwpIikrDQogIHlsaW0oMC42LCAxLjIpKyAgDQogIHNjYWxlX3hfZGlzY3JldGUobGFiZWxzPWMoIiIsIktsZWluIiwiIiwiIiwiU29tZXRoaW5nIFNwZWNpYWwiLCIiKSkrDQogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBHZW5vLmNvbG9ycy5vKSsgDQogIHN0YXRfcHZhbHVlX21hbnVhbChkYXRhPVRvbF9TY29yZUZfTTFfbG0ucCwgIHkucG9zaXRpb249MSwgc3RlcC5pbmNyZWFzZT0wLjMsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfU2NvcmVGX00xX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ29sb3IgU2NvcmUgRnVsbCBTZXQgV2ludGVyIFRpbWVwb2ludCBNNA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTQkU2NvcmVfRnVsbC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfTTQkU2NvcmVfRnVsbC5wcm9wKQ0KI05vdCBOb3JtYWwNCg0KIyNUcnkgc3F1YXJlIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhX000JFNjb3JlX0Z1bGwucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApXjIpDQojTm90IE5vcm1hbA0KDQojI1RyeSBjdWJlZCB0cmFuc2Zvcm1hdGlvbg0KaGlzdCgoVG9sRGF0YV9NNCRTY29yZV9GdWxsLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGFfTTQkU2NvcmVfRnVsbC5wcm9wKV4zKQ0KI05vdCBOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlRl9NNF9sbTwtbG0oU2NvcmVfRnVsbC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX000KQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlRl9NNF9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVGX000X2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVGX000X2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZUZfTTRfbG0pLCByZXNpZChUb2xfU2NvcmVGX000X2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZUZfTTRfbG0pDQphbm92YShUb2xfU2NvcmVGX000X2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlRl9NNF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZUZfTTRfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZUZfTTRfbG0pKQ0KVG9sX1Njb3JlRl9NNF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVGX000X2xtLnJlcykNClRvbF9TY29yZUZfTTRfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZUZfTTRfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlRl9NNF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfRnVsbFNldCIsIG5yb3coVG9sX1Njb3JlRl9NNF9sbS5yZXMpKQ0KVG9sX1Njb3JlRl9NNF9sbS5yZXMkVGltZVA8LXJlcCgiTTQiLCBucm93KFRvbF9TY29yZUZfTTRfbG0ucmVzKSkNClRvbF9TY29yZUZfTTRfbG0ucmVzPC1Ub2xfU2NvcmVGX000X2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQoNClNpZ25pZmljYW50IGVmZmVjdCBvZiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1Njb3JlRl9NNF9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KZW1tZWFucyhUb2xfU2NvcmVGX000X2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX1Njb3JlRl9NNF9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlRl9NNF9sbSwgcGFpcndpc2V+R2Vub3R5cGUgfCBTaXRlKSRjb250cmFzdHMpDQpUb2xfU2NvcmVGX000X2xtLmdlbm88LVRvbF9TY29yZUZfTTRfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZUZfTTRfbG0uZ2VubyRncm91cDE8LXBhc3RlKFRvbF9TY29yZUZfTTRfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVGX000X2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1Njb3JlRl9NNF9sbS5nZW5vJGdyb3VwMjwtcGFzdGUoVG9sX1Njb3JlRl9NNF9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZUZfTTRfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU2NvcmVGX000X2xtLnNpdGU8LWRhdGEuZnJhbWUoZW1tZWFucyhUb2xfU2NvcmVGX000X2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9TY29yZUZfTTRfbG0uc2l0ZTwtVG9sX1Njb3JlRl9NNF9sbS5zaXRlICU+JSBzZXBhcmF0ZShjb2w9Y29udHJhc3QsIGludG89YygiZ3JvdXAxIiwgImdyb3VwMiIpLCBzZXA9IiAtICIsIHJlbW92ZT1UUlVFKQ0KVG9sX1Njb3JlRl9NNF9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlRl9NNF9sbS5zaXRlJGdyb3VwMSwgVG9sX1Njb3JlRl9NNF9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KVG9sX1Njb3JlRl9NNF9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX1Njb3JlRl9NNF9sbS5zaXRlJGdyb3VwMiwgVG9sX1Njb3JlRl9NNF9sbS5zaXRlJEdlbm90eXBlLCBzZXA9Il8iKQ0KDQojRnVsbCBsaXN0IG9mIHAtdmFsdWVzDQpUb2xfU2NvcmVGX000X2xtLnA8LXJiaW5kKFRvbF9TY29yZUZfTTRfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TY29yZUZfTTRfbG0uc2l0ZVssYygxOjIsNDo4KV0pDQpUb2xfU2NvcmVGX000X2xtLnA8LVRvbF9TY29yZUZfTTRfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1Njb3JlRl9NNF9sbS5wJFNpZzwtaWZlbHNlKFRvbF9TY29yZUZfTTRfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9TY29yZUZfTTRfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU2NvcmVGX000X2xtLnAkcDwwLjA1LCAiKiIsIE5BKSkpDQoNCiNTcGVjaWZ5IFJlc3BvbnNlIGFuZCBUaW1lcG9pbnQNClRvbF9TY29yZUZfTTRfbG0ucCRSZXNwb25zZTwtcmVwKCJDb2xvcl9GdWxsU2V0IiwgbnJvdyhUb2xfU2NvcmVGX000X2xtLnApKQ0KVG9sX1Njb3JlRl9NNF9sbS5wJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfU2NvcmVGX000X2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZUZfTTRfU0c8LXN1bW1hcnlTRShUb2xEYXRhX000LCBtZWFzdXJldmFyPSJTY29yZV9GdWxsLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfU2NvcmVGX000X1NHLnBsb3Q8LWdncGxvdChUb2xfU2NvcmVGX000X1NHLCBhZXMoeD1TaXRlLkdlbm8sIHk9U2NvcmVfRnVsbC5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNjb3JlX0Z1bGwucHJvcC1zZSwgeW1heD1TY29yZV9GdWxsLnByb3Arc2UpLCB3aWR0aD1jYXAuc3osIGxpbmV3aWR0aD1iYXIuc3opKw0KICBnZW9tX3BvaW50KHNpemU9cG9pbnQuc3opKyANCiAgdGhlbWVfY2xhc3NpYygpKw0KICB0aGVtZSggYXhpcy50aXRsZS54ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgICBheGlzLnRpdGxlLnkgPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3osIGNvbG91cj0iYmxhY2siKSwgDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIGxlZ2VuZC5ib3guYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChjb2xvciA9ICJibGFjayIpLA0KICAgICAgICBsZWdlbmQucG9zaXRpb249ImJvdHRvbSIsIA0KICAgICAgICBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwNCiAgICAgICAgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkrDQogIGxhYnMoeD0iIiwgeT0iUHJvcG9ydGlvbiBDb2xvciBSZXRhaW5lZCAoRnVsbCkiKSsNCiAgeWxpbSgwLjYsIDEuMikrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVGX000X2xtLnAsICB5LnBvc2l0aW9uPTEuMDUsIHN0ZXAuaW5jcmVhc2U9MC4zNSwgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZUZfTTRfU0cucGxvdA0KDQpgYGANCg0KDQojIFRoZXJtYWwgVG9sZXJhbmNlIENvbG9yIGJ5IFRpbWVwb2ludA0KDQojIyBGdWxsIFNldA0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGEkU2NvcmVfVFAucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhJFNjb3JlX1RQLnByb3ApDQojTm90IE5vcm1hbA0KDQojI1RyeSBzcXVhcmUgdHJhbnNmb3JtYXRpb24NCmhpc3QoKFRvbERhdGEkU2NvcmVfVFAucHJvcCleMikNCnNoYXBpcm8udGVzdCgoVG9sRGF0YSRTY29yZV9UUC5wcm9wKV4yKQ0KI05vdCBub3JtYWwgDQoNCiMjVHJ5IGN1YmVkIHRyYW5zZm9ybWF0aW9uDQpoaXN0KChUb2xEYXRhJFNjb3JlX1RQLnByb3ApXjMpDQpzaGFwaXJvLnRlc3QoKFRvbERhdGEkU2NvcmVfVFAucHJvcCleMykNCiNOb3Qgbm9ybWFsIA0KDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZSBhbmQgVGltZXBvaW50DQojI01vZGVsIHdpdGggbm8gdHJhbnNmb3JtYXRpb24gYW5kIGNoZWNrIHJlc2lkdWFscw0KVG9sX1Njb3JlVFBfbG08LWxtKFNjb3JlX1RQLnByb3B+U2l0ZStHZW5vdHlwZStUaW1lUCsgU2l0ZTpHZW5vdHlwZSArIFNpdGU6VGltZVAgKyBHZW5vdHlwZTpUaW1lUCwgZGF0YT1Ub2xEYXRhKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlVFBfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlVFBfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZVRQX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZVRQX2xtKSwgcmVzaWQoVG9sX1Njb3JlVFBfbG0pKQ0KDQpgYGANCg0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlVFBfbG0pDQphbm92YShUb2xfU2NvcmVUUF9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9TY29yZVRQX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlVFBfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZVRQX2xtKSkNClRvbF9TY29yZVRQX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZVRQX2xtLnJlcykNClRvbF9TY29yZVRQX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVUUF9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfVFAiLCBucm93KFRvbF9TY29yZVRQX2xtLnJlcykpDQpUb2xfU2NvcmVUUF9sbS5yZXM8LVRvbF9TY29yZVRQX2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQpTdHJvbmcgaW5mbHVlbmNlIG9mIFRpbWVwb2ludCwgaW5jbHVkaW5nIGludGVyYWN0aW9ucyB3aXRoIHZhcmlhYmxlcyBvZiBpbnRlcmVzdCwgU2l0ZSBhbmQgR2Vub3R5cGUuIFdpbGwgYW5hbHl6ZSBlYWNoIFRpbWVwb2ludCBpbmRpdmlkdWFsbHkuIA0KDQoNCiMjIENvbG9yIFNjb3JlIGJ5IFRpbWVwb2ludCBTdW1tZXIgMSBUaW1lcG9pbnQgVzINCg0KIyMjIFJ1biBNb2RlbA0KYGBge3J9DQojI0NoZWNrIG5vcm1hbGl0eQ0KaGlzdChUb2xEYXRhX1cyJFNjb3JlX1RQLnByb3ApDQpzaGFwaXJvLnRlc3QoVG9sRGF0YV9XMiRTY29yZV9UUC5wcm9wKQ0KI05vcm1hbA0KDQojI01vZGVsIGFzIGEgZnVuY3Rpb24gb2YgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZVRQX1cyX2xtPC1sbShTY29yZV9UUC5wcm9wflNpdGUrR2Vub3R5cGUrU2l0ZTpHZW5vdHlwZSwgZGF0YT1Ub2xEYXRhX1cyKQ0KDQpgYGANCg0KDQojIyMjIENoZWNrIFJlc2lkdWFscw0KYGBge3J9DQojI0NoZWNrIE5vcm1hbGl0eSBvZiBSZXNpZHVhbHMNCiNEaXN0cmlidXRpb24gDQpwbG90KGRlbnNpdHkocmVzaWQoVG9sX1Njb3JlVFBfVzJfbG0pKSkNCg0KI1EtUSBwbG90DQpxcW5vcm0ocmVzaWQoVG9sX1Njb3JlVFBfVzJfbG0pKTsgcXFsaW5lKHJlc2lkKFRvbF9TY29yZVRQX1cyX2xtKSkNCg0KIyNDaGVjayBWYXJpYW5jZSBvZiBSZXNpZHVhbHMgYWNyb3NzIEZpdHRlZCBWYWx1ZXMNCnBsb3QoZml0dGVkKFRvbF9TY29yZVRQX1cyX2xtKSwgcmVzaWQoVG9sX1Njb3JlVFBfVzJfbG0pKQ0KDQpgYGANCg0KDQojIyMgTW9kZWwgUmVzdWx0cw0KDQojIyMjIE92ZXJhbGwNCmBgYHtyfQ0KI01vZGVsIFJlc3VsdHMNCnN1bW1hcnkoVG9sX1Njb3JlVFBfVzJfbG0pDQphbm92YShUb2xfU2NvcmVUUF9XMl9sbSkNCg0KI0VmZmVjdCBTaXplIG9mIFByZWRpY3RvcnMNCmV0YV9zcXVhcmVkKFRvbF9TY29yZVRQX1cyX2xtLCBwYXJ0aWFsPUZBTFNFKQ0KDQojI1NhdmUgbW9kZWwgcmVzdWx0cw0KVG9sX1Njb3JlVFBfVzJfbG0ucmVzPC1kYXRhLmZyYW1lKGFub3ZhKFRvbF9TY29yZVRQX1cyX2xtKSkNClRvbF9TY29yZVRQX1cyX2xtLnJlcyRQcmVkaWN0b3I8LXJvd25hbWVzKFRvbF9TY29yZVRQX1cyX2xtLnJlcykNClRvbF9TY29yZVRQX1cyX2xtLnJlcyRFdGFTcTwtYyhldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9XMl9sbSwgcGFydGlhbD1GQUxTRSkkRXRhMiwgTkEpDQpUb2xfU2NvcmVUUF9XMl9sbS5yZXMkUmVzcG9uc2U8LXJlcCgiQ29sb3JfVFAiLCBucm93KFRvbF9TY29yZVRQX1cyX2xtLnJlcykpDQpUb2xfU2NvcmVUUF9XMl9sbS5yZXMkVGltZVA8LXJlcCgiVzIiLCBucm93KFRvbF9TY29yZVRQX1cyX2xtLnJlcykpDQpUb2xfU2NvcmVUUF9XMl9sbS5yZXM8LVRvbF9TY29yZVRQX1cyX2xtLnJlcyAlPiUgZHBseXI6OnJlbmFtZSggcC52YWx1ZSA9ICJQci4uRi4iLCBERj0gIkRmIikNCg0KYGBgDQoNClNpZ25pZmljYW50IGVmZmVjdCBvZiBHZW5vdHlwZS4gU3RpbGwgY2hlY2tpbmcgU2l0ZSpHZW5vdHlwZSBmb3IgY29tcGFyYWJpbGl0eSBhY3Jvc3MgVGltZXBvaW50cy4NCg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVUUF9XMl9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfVzJfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfVzJfbG0uZ2VubzwtVG9sX1Njb3JlVFBfVzJfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX1cyX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9XMl9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX1cyX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1Njb3JlVFBfVzJfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZVRQX1cyX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlVFBfVzJfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU2NvcmVUUF9XMl9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfVzJfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZTwtVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX1cyX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9XMl9sbS5zaXRlJGdyb3VwMSwgVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZVRQX1cyX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9XMl9sbS5zaXRlJGdyb3VwMiwgVG9sX1Njb3JlVFBfVzJfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlVFBfVzJfbG0ucDwtcmJpbmQoVG9sX1Njb3JlVFBfVzJfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TY29yZVRQX1cyX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlVFBfVzJfbG0ucDwtVG9sX1Njb3JlVFBfVzJfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1Njb3JlVFBfVzJfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVUUF9XMl9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfVzJfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU2NvcmVUUF9XMl9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVUUF9XMl9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9XMl9sbS5wKSkNClRvbF9TY29yZVRQX1cyX2xtLnAkVGltZVA8LXJlcCgiVzIiLCBucm93KFRvbF9TY29yZVRQX1cyX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZVRQX1cyX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9XMiwgbWVhc3VyZXZhcj0iU2NvcmVfVFAucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZVRQX1cyX1NHLnBsb3Q8LWdncGxvdChUb2xfU2NvcmVUUF9XMl9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX1RQLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfVFAucHJvcC1zZSwgeW1heD1TY29yZV9UUC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gQ29sb3IgUmV0YWluZWQgKFRQKSIpKw0KICB5bGltKDAuNiwgMS4yKSsgIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVUUF9XMl9sbS5wLCAgeS5wb3NpdGlvbj0xLCBzdGVwLmluY3JlYXNlPTAuMywgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX1cyX1NHLnBsb3QNCg0KYGBgDQoNCg0KIyMgQ29sb3IgU2NvcmUgYnkgVGltZXBvaW50IFN1bW1lciAyIFRpbWVwb2ludCBNMQ0KDQojIyMgUnVuIE1vZGVsDQpgYGB7cn0NCiMjQ2hlY2sgbm9ybWFsaXR5DQpoaXN0KFRvbERhdGFfTTEkU2NvcmVfVFAucHJvcCkNCnNoYXBpcm8udGVzdChUb2xEYXRhX00xJFNjb3JlX1RQLnByb3ApDQojTm9ybWFsDQoNCiMjTW9kZWwgYXMgYSBmdW5jdGlvbiBvZiBTaXRlIGFuZCBHZW5vdHlwZQ0KVG9sX1Njb3JlVFBfTTFfbG08LWxtKFNjb3JlX1RQLnByb3B+U2l0ZStHZW5vdHlwZStTaXRlOkdlbm90eXBlLCBkYXRhPVRvbERhdGFfTTEpDQoNCmBgYA0KDQoNCiMjIyMgQ2hlY2sgUmVzaWR1YWxzDQpgYGB7cn0NCiMjQ2hlY2sgTm9ybWFsaXR5IG9mIFJlc2lkdWFscw0KI0Rpc3RyaWJ1dGlvbiANCnBsb3QoZGVuc2l0eShyZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpKQ0KDQojUS1RIHBsb3QNCnFxbm9ybShyZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpOyBxcWxpbmUocmVzaWQoVG9sX1Njb3JlVFBfTTFfbG0pKQ0KDQojI0NoZWNrIFZhcmlhbmNlIG9mIFJlc2lkdWFscyBhY3Jvc3MgRml0dGVkIFZhbHVlcw0KcGxvdChmaXR0ZWQoVG9sX1Njb3JlVFBfTTFfbG0pLCByZXNpZChUb2xfU2NvcmVUUF9NMV9sbSkpDQoNCmBgYA0KDQoNCiMjIyBNb2RlbCBSZXN1bHRzDQoNCiMjIyMgT3ZlcmFsbA0KYGBge3J9DQojTW9kZWwgUmVzdWx0cw0Kc3VtbWFyeShUb2xfU2NvcmVUUF9NMV9sbSkNCmFub3ZhKFRvbF9TY29yZVRQX00xX2xtKQ0KDQojRWZmZWN0IFNpemUgb2YgUHJlZGljdG9ycw0KZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfTTFfbG0sIHBhcnRpYWw9RkFMU0UpDQoNCiMjU2F2ZSBtb2RlbCByZXN1bHRzDQpUb2xfU2NvcmVUUF9NMV9sbS5yZXM8LWRhdGEuZnJhbWUoYW5vdmEoVG9sX1Njb3JlVFBfTTFfbG0pKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucmVzJFByZWRpY3Rvcjwtcm93bmFtZXMoVG9sX1Njb3JlVFBfTTFfbG0ucmVzKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucmVzJEV0YVNxPC1jKGV0YV9zcXVhcmVkKFRvbF9TY29yZVRQX00xX2xtLCBwYXJ0aWFsPUZBTFNFKSRFdGEyLCBOQSkNClRvbF9TY29yZVRQX00xX2xtLnJlcyRSZXNwb25zZTwtcmVwKCJDb2xvcl9UUCIsIG5yb3coVG9sX1Njb3JlVFBfTTFfbG0ucmVzKSkNClRvbF9TY29yZVRQX00xX2xtLnJlcyRUaW1lUDwtcmVwKCJNMSIsIG5yb3coVG9sX1Njb3JlVFBfTTFfbG0ucmVzKSkNClRvbF9TY29yZVRQX00xX2xtLnJlczwtVG9sX1Njb3JlVFBfTTFfbG0ucmVzICU+JSBkcGx5cjo6cmVuYW1lKCBwLnZhbHVlID0gIlByLi5GLiIsIERGPSAiRGYiKQ0KDQpgYGANCg0KU2lnbmlmaWNhbnQgZWZmZWN0IG9mIFNpdGUgYW5kIEdlbm90eXBlLiBTdGlsbCBjaGVja2luZyBTaXRlKkdlbm90eXBlIGZvciBjb21wYXJhYmlsaXR5IGFjcm9zcyBUaW1lcG9pbnRzLg0KDQoNCiMjIyMgUGFpcndpc2UNCmBgYHtyfQ0KI1BhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zczoNCg0KI0dlbm90eXBlcyB3aXRoaW4gU2l0ZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkNCg0KI1NpdGVzIHdpdGhpbiBHZW5vdHlwZXMNCmVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkNCg0KIyNTYXZlIHAtdmFsdWVzDQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQpUb2xfU2NvcmVUUF9NMV9sbS5nZW5vPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlfkdlbm90eXBlIHwgU2l0ZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTFfbG0uZ2VubzwtVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX00xX2xtLmdlbm8kZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX00xX2xtLmdlbm8kZ3JvdXAxLCBzZXA9Il8iKQ0KVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyRncm91cDI8LXBhc3RlKFRvbF9TY29yZVRQX00xX2xtLmdlbm8kU2l0ZSwgVG9sX1Njb3JlVFBfTTFfbG0uZ2VubyRncm91cDIsIHNlcD0iXyIpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQpUb2xfU2NvcmVUUF9NMV9sbS5zaXRlPC1kYXRhLmZyYW1lKGVtbWVhbnMoVG9sX1Njb3JlVFBfTTFfbG0sIHBhaXJ3aXNlflNpdGUgfCBHZW5vdHlwZSkkY29udHJhc3RzKQ0KVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZTwtVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSAlPiUgc2VwYXJhdGUoY29sPWNvbnRyYXN0LCBpbnRvPWMoImdyb3VwMSIsICJncm91cDIiKSwgc2VwPSIgLSAiLCByZW1vdmU9VFJVRSkNClRvbF9TY29yZVRQX00xX2xtLnNpdGUkZ3JvdXAxPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5zaXRlJGdyb3VwMSwgVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNClRvbF9TY29yZVRQX00xX2xtLnNpdGUkZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9NMV9sbS5zaXRlJGdyb3VwMiwgVG9sX1Njb3JlVFBfTTFfbG0uc2l0ZSRHZW5vdHlwZSwgc2VwPSJfIikNCg0KI0Z1bGwgbGlzdCBvZiBwLXZhbHVlcw0KVG9sX1Njb3JlVFBfTTFfbG0ucDwtcmJpbmQoVG9sX1Njb3JlVFBfTTFfbG0uZ2Vub1ssYygxOjIsNDo4KV0sIFRvbF9TY29yZVRQX00xX2xtLnNpdGVbLGMoMToyLDQ6OCldKQ0KVG9sX1Njb3JlVFBfTTFfbG0ucDwtVG9sX1Njb3JlVFBfTTFfbG0ucCAlPiUgZHBseXI6OnJlbmFtZSggcCA9IHAudmFsdWUpDQoNCiNBZGQgU2lnbmlmaWNhbmNlIExldmVscw0KVG9sX1Njb3JlVFBfTTFfbG0ucCRTaWc8LWlmZWxzZShUb2xfU2NvcmVUUF9NMV9sbS5wJHA8MC4wMDEsICIqKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfTTFfbG0ucCRwPDAuMDEsICIqKiIsIGlmZWxzZShUb2xfU2NvcmVUUF9NMV9sbS5wJHA8MC4wNSwgIioiLCBOQSkpKQ0KDQojU3BlY2lmeSBSZXNwb25zZSBhbmQgVGltZXBvaW50DQpUb2xfU2NvcmVUUF9NMV9sbS5wJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9NMV9sbS5wKSkNClRvbF9TY29yZVRQX00xX2xtLnAkVGltZVA8LXJlcCgiTTEiLCBucm93KFRvbF9TY29yZVRQX00xX2xtLnApKQ0KDQpgYGANCg0KDQojIyMgUGxvdCBSZXRlbnRpb24gYnkgU2l0ZSBhbmQgR2Vub3R5cGUNCmBgYHtyfQ0KIyNTdW1tYXJ5IHN0YXRpc3RpY3MgYnkgU2l0ZSBhbmQgR2Vub3R5cGUNClRvbF9TY29yZVRQX00xX1NHPC1zdW1tYXJ5U0UoVG9sRGF0YV9NMSwgbWVhc3VyZXZhcj0iU2NvcmVfVFAucHJvcCIsIGdyb3VwdmFycz1jKCJTaXRlLkdlbm8iLCAiU2l0ZSIsICJHZW5vdHlwZSIpLCBuYS5ybT1UUlVFKQ0KDQojI1Bsb3QgQXZlcmFnZSBSZXRlbnRpb24gYWNyb3NzIFRyZWF0bWVudHMNClRvbF9TY29yZVRQX00xX1NHLnBsb3Q8LWdncGxvdChUb2xfU2NvcmVUUF9NMV9TRywgYWVzKHg9U2l0ZS5HZW5vLCB5PVNjb3JlX1RQLnByb3AsIGNvbG91cj1HZW5vdHlwZSkpICsgDQogIGdlb21fZXJyb3JiYXIoYWVzKHltaW49U2NvcmVfVFAucHJvcC1zZSwgeW1heD1TY29yZV9UUC5wcm9wK3NlKSwgd2lkdGg9Y2FwLnN6LCBsaW5ld2lkdGg9YmFyLnN6KSsNCiAgZ2VvbV9wb2ludChzaXplPXBvaW50LnN6KSsgDQogIHRoZW1lX2NsYXNzaWMoKSsNCiAgdGhlbWUoIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICAgYXhpcy50aXRsZS55ID0gZWxlbWVudF90ZXh0KHNpemUgPSBheGlzLnRpdGxlLnN6KSwgDQogICAgICAgIGF4aXMudGV4dC54PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGF4aXMudGV4dC55PWVsZW1lbnRfdGV4dChzaXplPWF4aXMudHh0LnN6LCBjb2xvdXI9ImJsYWNrIiksIA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBsZWdlbmQuYm94LmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoY29sb3IgPSAiYmxhY2siKSwNCiAgICAgICAgbGVnZW5kLnBvc2l0aW9uPSJib3R0b20iLCANCiAgICAgICAgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IlByb3BvcnRpb24gQ29sb3IgUmV0YWluZWQgKFRQKSIpKw0KICB5bGltKDAuNiwgMS4yKSsgIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVUUF9NMV9sbS5wLCAgeS5wb3NpdGlvbj0xLCBzdGVwLmluY3JlYXNlPTAuMjUsIGxhYmVsPSJTaWciLCBoaWRlLm5zPVRSVUUpOyBUb2xfU2NvcmVUUF9NMV9TRy5wbG90DQoNCmBgYA0KDQoNCiMjIENvbG9yIFNjb3JlIGJ5IFRpbWVwb2ludCBXaW50ZXIgVGltZXBvaW50IE00DQoNCiMjIyBSdW4gTW9kZWwNCmBgYHtyfQ0KIyNDaGVjayBub3JtYWxpdHkNCmhpc3QoVG9sRGF0YV9NNCRTY29yZV9UUC5wcm9wKQ0Kc2hhcGlyby50ZXN0KFRvbERhdGFfTTQkU2NvcmVfVFAucHJvcCkNCiNOb3JtYWwNCg0KIyNNb2RlbCBhcyBhIGZ1bmN0aW9uIG9mIFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVUUF9NNF9sbTwtbG0oU2NvcmVfVFAucHJvcH5TaXRlK0dlbm90eXBlK1NpdGU6R2Vub3R5cGUsIGRhdGE9VG9sRGF0YV9NNCkNCg0KYGBgDQoNCg0KIyMjIyBDaGVjayBSZXNpZHVhbHMNCmBgYHtyfQ0KIyNDaGVjayBOb3JtYWxpdHkgb2YgUmVzaWR1YWxzDQojRGlzdHJpYnV0aW9uIA0KcGxvdChkZW5zaXR5KHJlc2lkKFRvbF9TY29yZVRQX000X2xtKSkpDQoNCiNRLVEgcGxvdA0KcXFub3JtKHJlc2lkKFRvbF9TY29yZVRQX000X2xtKSk7IHFxbGluZShyZXNpZChUb2xfU2NvcmVUUF9NNF9sbSkpDQoNCiMjQ2hlY2sgVmFyaWFuY2Ugb2YgUmVzaWR1YWxzIGFjcm9zcyBGaXR0ZWQgVmFsdWVzDQpwbG90KGZpdHRlZChUb2xfU2NvcmVUUF9NNF9sbSksIHJlc2lkKFRvbF9TY29yZVRQX000X2xtKSkNCg0KYGBgDQoNCg0KIyMjIE1vZGVsIFJlc3VsdHMNCg0KIyMjIyBPdmVyYWxsDQpgYGB7cn0NCiNNb2RlbCBSZXN1bHRzDQpzdW1tYXJ5KFRvbF9TY29yZVRQX000X2xtKQ0KYW5vdmEoVG9sX1Njb3JlVFBfTTRfbG0pDQoNCiNFZmZlY3QgU2l6ZSBvZiBQcmVkaWN0b3JzDQpldGFfc3F1YXJlZChUb2xfU2NvcmVUUF9NNF9sbSwgcGFydGlhbD1GQUxTRSkNCg0KIyNTYXZlIG1vZGVsIHJlc3VsdHMNClRvbF9TY29yZVRQX000X2xtLnJlczwtZGF0YS5mcmFtZShhbm92YShUb2xfU2NvcmVUUF9NNF9sbSkpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXMkUHJlZGljdG9yPC1yb3duYW1lcyhUb2xfU2NvcmVUUF9NNF9sbS5yZXMpDQpUb2xfU2NvcmVUUF9NNF9sbS5yZXMkRXRhU3E8LWMoZXRhX3NxdWFyZWQoVG9sX1Njb3JlVFBfTTRfbG0sIHBhcnRpYWw9RkFMU0UpJEV0YTIsIE5BKQ0KVG9sX1Njb3JlVFBfTTRfbG0ucmVzJFJlc3BvbnNlPC1yZXAoIkNvbG9yX1RQIiwgbnJvdyhUb2xfU2NvcmVUUF9NNF9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfTTRfbG0ucmVzJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfU2NvcmVUUF9NNF9sbS5yZXMpKQ0KVG9sX1Njb3JlVFBfTTRfbG0ucmVzPC1Ub2xfU2NvcmVUUF9NNF9sbS5yZXMgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSAiUHIuLkYuIiwgREY9ICJEZiIpDQoNCmBgYA0KDQpTaWduaWZpY2FudCBlZmZlY3Qgb2YgR2Vub3R5cGUuIFN0aWxsIGNoZWNraW5nIFNpdGUqR2Vub3R5cGUgZm9yIGNvbXBhcmFiaWxpdHkgYWNyb3NzIFRpbWVwb2ludHMuDQoNCg0KDQojIyMjIFBhaXJ3aXNlDQpgYGB7cn0NCiNQYWlyd2lzZSBjb21wYXJpc29ucyBhY3Jvc3M6DQoNCiNHZW5vdHlwZXMgd2l0aGluIFNpdGVzDQplbW1lYW5zKFRvbF9TY29yZVRQX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpDQoNCiNTaXRlcyB3aXRoaW4gR2Vub3R5cGVzDQplbW1lYW5zKFRvbF9TY29yZVRQX000X2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpDQoNCiMjU2F2ZSBwLXZhbHVlcw0KDQojR2Vub3R5cGVzIHdpdGhpbiBTaXRlcw0KVG9sX1Njb3JlVFBfTTRfbG0uZ2VubzwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZVRQX000X2xtLCBwYWlyd2lzZX5HZW5vdHlwZSB8IFNpdGUpJGNvbnRyYXN0cykNClRvbF9TY29yZVRQX000X2xtLmdlbm88LVRvbF9TY29yZVRQX000X2xtLmdlbm8gJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVUUF9NNF9sbS5nZW5vJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlVFBfTTRfbG0uZ2VubyRTaXRlLCBUb2xfU2NvcmVUUF9NNF9sbS5nZW5vJGdyb3VwMSwgc2VwPSJfIikNClRvbF9TY29yZVRQX000X2xtLmdlbm8kZ3JvdXAyPC1wYXN0ZShUb2xfU2NvcmVUUF9NNF9sbS5nZW5vJFNpdGUsIFRvbF9TY29yZVRQX000X2xtLmdlbm8kZ3JvdXAyLCBzZXA9Il8iKQ0KDQojU2l0ZXMgd2l0aGluIEdlbm90eXBlcw0KVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZTwtZGF0YS5mcmFtZShlbW1lYW5zKFRvbF9TY29yZVRQX000X2xtLCBwYWlyd2lzZX5TaXRlIHwgR2Vub3R5cGUpJGNvbnRyYXN0cykNClRvbF9TY29yZVRQX000X2xtLnNpdGU8LVRvbF9TY29yZVRQX000X2xtLnNpdGUgJT4lIHNlcGFyYXRlKGNvbD1jb250cmFzdCwgaW50bz1jKCJncm91cDEiLCAiZ3JvdXAyIiksIHNlcD0iIC0gIiwgcmVtb3ZlPVRSVUUpDQpUb2xfU2NvcmVUUF9NNF9sbS5zaXRlJGdyb3VwMTwtcGFzdGUoVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSRncm91cDEsIFRvbF9TY29yZVRQX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQpUb2xfU2NvcmVUUF9NNF9sbS5zaXRlJGdyb3VwMjwtcGFzdGUoVG9sX1Njb3JlVFBfTTRfbG0uc2l0ZSRncm91cDIsIFRvbF9TY29yZVRQX000X2xtLnNpdGUkR2Vub3R5cGUsIHNlcD0iXyIpDQoNCiNGdWxsIGxpc3Qgb2YgcC12YWx1ZXMNClRvbF9TY29yZVRQX000X2xtLnA8LXJiaW5kKFRvbF9TY29yZVRQX000X2xtLmdlbm9bLGMoMToyLDQ6OCldLCBUb2xfU2NvcmVUUF9NNF9sbS5zaXRlWyxjKDE6Miw0OjgpXSkNClRvbF9TY29yZVRQX000X2xtLnA8LVRvbF9TY29yZVRQX000X2xtLnAgJT4lIGRwbHlyOjpyZW5hbWUoIHAgPSBwLnZhbHVlKQ0KDQojQWRkIFNpZ25pZmljYW5jZSBMZXZlbHMNClRvbF9TY29yZVRQX000X2xtLnAkU2lnPC1pZmVsc2UoVG9sX1Njb3JlVFBfTTRfbG0ucCRwPDAuMDAxLCAiKioqIiwgaWZlbHNlKFRvbF9TY29yZVRQX000X2xtLnAkcDwwLjAxLCAiKioiLCBpZmVsc2UoVG9sX1Njb3JlVFBfTTRfbG0ucCRwPDAuMDUsICIqIiwgTkEpKSkNCg0KI1NwZWNpZnkgUmVzcG9uc2UgYW5kIFRpbWVwb2ludA0KVG9sX1Njb3JlVFBfTTRfbG0ucCRSZXNwb25zZTwtcmVwKCJDb2xvcl9UUCIsIG5yb3coVG9sX1Njb3JlVFBfTTRfbG0ucCkpDQpUb2xfU2NvcmVUUF9NNF9sbS5wJFRpbWVQPC1yZXAoIk00IiwgbnJvdyhUb2xfU2NvcmVUUF9NNF9sbS5wKSkNCg0KYGBgDQoNCg0KIyMjIFBsb3QgUmV0ZW50aW9uIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpgYGB7cn0NCiMjU3VtbWFyeSBzdGF0aXN0aWNzIGJ5IFNpdGUgYW5kIEdlbm90eXBlDQpUb2xfU2NvcmVUUF9NNF9TRzwtc3VtbWFyeVNFKFRvbERhdGFfTTQsIG1lYXN1cmV2YXI9IlNjb3JlX1RQLnByb3AiLCBncm91cHZhcnM9YygiU2l0ZS5HZW5vIiwgIlNpdGUiLCAiR2Vub3R5cGUiKSwgbmEucm09VFJVRSkNCg0KIyNQbG90IEF2ZXJhZ2UgUmV0ZW50aW9uIGFjcm9zcyBUcmVhdG1lbnRzDQpUb2xfU2NvcmVUUF9NNF9TRy5wbG90PC1nZ3Bsb3QoVG9sX1Njb3JlVFBfTTRfU0csIGFlcyh4PVNpdGUuR2VubywgeT1TY29yZV9UUC5wcm9wLCBjb2xvdXI9R2Vub3R5cGUpKSArIA0KICBnZW9tX2Vycm9yYmFyKGFlcyh5bWluPVNjb3JlX1RQLnByb3Atc2UsIHltYXg9U2NvcmVfVFAucHJvcCtzZSksIHdpZHRoPWNhcC5zeiwgbGluZXdpZHRoPWJhci5zeikrDQogIGdlb21fcG9pbnQoc2l6ZT1wb2ludC5zeikrIA0KICB0aGVtZV9jbGFzc2ljKCkrDQogIHRoZW1lKCBheGlzLnRpdGxlLnggPSBlbGVtZW50X3RleHQoc2l6ZSA9IGF4aXMudGl0bGUuc3opLCANCiAgICAgICAgIGF4aXMudGl0bGUueSA9IGVsZW1lbnRfdGV4dChzaXplID0gYXhpcy50aXRsZS5zeiksIA0KICAgICAgICBheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zeiwgY29sb3VyPSJibGFjayIpLCANCiAgICAgICAgbGVnZW5kLnRleHQ9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnR4dC5zeiksDQogICAgICAgIGxlZ2VuZC50aXRsZT1lbGVtZW50X3RleHQoc2l6ZT1sZWcudGl0bGUuc3opLCANCiAgICAgICAgbGVnZW5kLmJveC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGNvbG9yID0gImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC5wb3NpdGlvbj0iYm90dG9tIiwgDQogICAgICAgIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSJQcm9wb3J0aW9uIENvbG9yIFJldGFpbmVkIChUUCkiKSsNCiAgeWxpbSgwLjYsIDEuMikrIA0KICBzY2FsZV94X2Rpc2NyZXRlKGxhYmVscz1jKCIiLCJLbGVpbiIsIiIsIiIsIlNvbWV0aGluZyBTcGVjaWFsIiwiIikpKw0KICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gR2Vuby5jb2xvcnMubykrIA0KICBzdGF0X3B2YWx1ZV9tYW51YWwoZGF0YT1Ub2xfU2NvcmVUUF9NNF9sbS5wLCAgeS5wb3NpdGlvbj0xLCBzdGVwLmluY3JlYXNlPTAuMywgbGFiZWw9IlNpZyIsIGhpZGUubnM9VFJVRSk7IFRvbF9TY29yZVRQX000X1NHLnBsb3QNCg0KYGBgDQoNCg0KIyBDb250cmFzdHMgQWNyb3NzIE1ldHJpY3MNCg0KIyMjIENvbWJpbmUgQ29udHJhc3QgUmVzdWx0cw0KQ3JlYXRpbmcgYSBoZWF0bWFwIHRvIGNvbXBhcmUgdGhlIGRpcmVjdGlvbiBhbmQgc2lnbmlmaWNhbmNlIG9mIHBhaXJ3aXNlIGNvbXBhcmlzb25zIGFjcm9zcyBUb2xlcmFuY2UgbWV0cmljcy4gUG9zaXRpdmUgZXN0aW1hdGVzIGluZGljYXRlIHRoYXQgR3JvdXAgMSA+IEdyb3VwIDIuIFAgdmFsdWVzIG9mIGxlc3MgdGhhbiAwLjA1IGFyZSBjb25zaWRlcmVkIHNpZ25pZmljYW50LiAgIA0KYGBge3J9DQojI0NvbWJpbmUgUmVzdWx0cw0KVG9sX2NvbnRyYXN0czwtcmJpbmQoVG9sX0NobF9XMl9sbS5wLCBUb2xfQ2hsX00xX2xtLnAsIFRvbF9DaGxfTTRfbG0ucCwgDQogICAgICAgICAgICAgICAgICAgICBUb2xfU3ltX1cyX2xtLnAsIFRvbF9TeW1fTTFfbG0ucCwgVG9sX1N5bV9NNF9sbS5wLCANCiAgICAgICAgICAgICAgICAgICAgIFRvbF9TY29yZUZfVzJfbG0ucCwgVG9sX1Njb3JlRl9NMV9sbS5wLCBUb2xfU2NvcmVGX000X2xtLnAsIA0KICAgICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfbG0ucCwgVG9sX1Njb3JlVFBfTTFfbG0ucCwgVG9sX1Njb3JlVFBfTTRfbG0ucCkNCg0KIyNDcmVhdGUgQ29udHJhc3QgQ29sdW1uDQpUb2xfY29udHJhc3RzJENvbnRyYXN0PC1wYXN0ZShUb2xfY29udHJhc3RzJGdyb3VwMSwgVG9sX2NvbnRyYXN0cyRncm91cDIsIHNlcD0iIHYuICIpDQoNCiMjQWRkIFNldCBjb2x1bW4gd2l0aCBDb250cmFzdCBhbmQgVGltZXBvaW50DQpUb2xfY29udHJhc3RzJFNldDwtcGFzdGUoVG9sX2NvbnRyYXN0cyRUaW1lUCwgVG9sX2NvbnRyYXN0cyRDb250cmFzdCwgc2VwPSIgIikNCg0KIyNSZS1vcmRlciBieSBTZWFzb25hbCBUaW1lcG9pbnQNClRvbF9jb250cmFzdHMkVGltZVA8LWZhY3RvcihUb2xfY29udHJhc3RzJFRpbWVQLCBsZXZlbHM9YygiVzIiLCAiTTEiLCAiTTQiKSwgb3JkZXJlZD1UUlVFKQ0KVG9sX2NvbnRyYXN0czwtIFRvbF9jb250cmFzdHMgJT4lIGFycmFuZ2UoZGVzYyhhcy5udW1lcmljKFRpbWVQKSkpDQoNClRvbF9jb250cmFzdHMkU2V0PC1mYWN0b3IoVG9sX2NvbnRyYXN0cyRTZXQsIGxldmVscz1jKHVuaXF1ZShUb2xfY29udHJhc3RzJFNldCkpLCBvcmRlcmVkPVRSVUUpDQpgYGANCg0KDQojIyMgU3RhbmRhcmRpemUgUmVzcG9uc2UgU2NhbGUNCkNvbnZlcnQgRXN0aW1hdGUgdG8gdGhlIFJlc3BvbnNlIHNjYWxlIChpbnN0ZWFkIG9mIGxvZyArMSBzY2FsZSkgZm9yIG1vZGVscyB3aGVyZSB0aGUgcmVzcG9uc2Ugd2FzIGxvZyB0cmFuc2Zvcm1lZA0KYGBge3J9DQpUb2xfY29udHJhc3RzJEVzdGltYXRlPC1Ub2xfY29udHJhc3RzJGVzdGltYXRlDQoNCiNDaGwgTTQNClRvbF9jb250cmFzdHMkRXN0aW1hdGVbd2hpY2goVG9sX2NvbnRyYXN0cyRSZXNwb25zZT09IkNobG9yb3BoeWxsIiAmIFRvbF9jb250cmFzdHMkVGltZVA9PSJNNCIpXTwtYyhleHAoVG9sX2NvbnRyYXN0cyRlc3RpbWF0ZVt3aGljaChUb2xfY29udHJhc3RzJFJlc3BvbnNlPT0iQ2hsb3JvcGh5bGwiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik00IildKS0xKQ0KDQojU3ltIE0xDQpUb2xfY29udHJhc3RzJEVzdGltYXRlW3doaWNoKFRvbF9jb250cmFzdHMkUmVzcG9uc2U9PSJTeW1iaW9udHMiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik0xIildPC1jKGV4cChUb2xfY29udHJhc3RzJGVzdGltYXRlW3doaWNoKFRvbF9jb250cmFzdHMkUmVzcG9uc2U9PSJTeW1iaW9udHMiICYgVG9sX2NvbnRyYXN0cyRUaW1lUD09Ik0xIildKS0xKQ0KDQoNCmBgYA0KDQoNCiMjIENvbnRyYXN0IEhlYXRtYXBzDQoNCiMjIyMgU3VtbWVyIDEgVGltZXBvaW50IFcyDQpgYGB7cn0NClRvbF9QYWlyc19XMi5wbG90PC1nZ3Bsb3QoZGF0YT1Ub2xfY29udHJhc3RzW3doaWNoKFRvbF9jb250cmFzdHMkVGltZVA9PSJXMiIpLF0sIGFlcyh4PVJlc3BvbnNlLCB5PUNvbnRyYXN0LCBmaWxsPUVzdGltYXRlKSkrDQogIGdlb21fdGlsZSgpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPVNpZyksIHNpemU9c2lnLnN6KSsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSIjQkExRTAyRkYiLCBtaWQ9IndoaXRlIiwgaGlnaD0iIzNCQTBGREZGIikrDQogIHRoZW1lX2J3KCkrDQogIGdndGl0bGUoIlBhaXJ3aXNlIENvbnRyYXN0cyBTdW1tZXIgMSIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzX1cyLnBsb3QNCmBgYA0KDQoNCiMjIyMgU3VtbWVyIDIgVGltZXBvaW50IE0xDQpgYGB7cn0NClRvbF9QYWlyc19NMS5wbG90PC1nZ3Bsb3QoZGF0YT1Ub2xfY29udHJhc3RzW3doaWNoKFRvbF9jb250cmFzdHMkVGltZVA9PSJNMSIpLF0sIGFlcyh4PVJlc3BvbnNlLCB5PUNvbnRyYXN0LCBmaWxsPUVzdGltYXRlKSkrDQogIGdlb21fdGlsZSgpKw0KICBnZW9tX3RleHQoYWVzKGxhYmVsPVNpZyksIHNpemU9c2lnLnN6KSsNCiAgc2NhbGVfZmlsbF9ncmFkaWVudDIobG93PSIjQkExRTAyRkYiLCBtaWQ9IndoaXRlIiwgaGlnaD0iIzNCQTBGREZGIikrDQogIHRoZW1lX2J3KCkrDQogIGdndGl0bGUoIlBhaXJ3aXNlIENvbnRyYXN0cyBTdW1tZXIgMiIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzX00xLnBsb3QNCmBgYA0KDQoNCiMjIyMgV2ludGVyIFRpbWVwb2ludCBNNA0KYGBge3J9DQpUb2xfUGFpcnNfTTQucGxvdDwtZ2dwbG90KGRhdGE9VG9sX2NvbnRyYXN0c1t3aGljaChUb2xfY29udHJhc3RzJFRpbWVQPT0iTTQiKSxdLCBhZXMoeD1SZXNwb25zZSwgeT1Db250cmFzdCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJQYWlyd2lzZSBDb250cmFzdHMgTW9udGggNCIpKw0KICB0aGVtZShheGlzLnRleHQueD1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgYW5nbGU9NDUsIGhqdXN0PTEpLA0KICAgICAgICBheGlzLnRleHQueT1lbGVtZW50X3RleHQoc2l6ZT1heGlzLnR4dC5zei0xLCBjb2xvdXI9ImJsYWNrIiksDQogICAgICAgIGxlZ2VuZC50ZXh0PWVsZW1lbnRfdGV4dChzaXplPWxlZy50eHQuc3opLA0KICAgICAgICBsZWdlbmQudGl0bGU9ZWxlbWVudF90ZXh0KHNpemU9bGVnLnRpdGxlLnN6KSwgDQogICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpKw0KICBsYWJzKHg9IiIsIHk9IiIsIGZpbGw9IkVzdGltYXRlIik7VG9sX1BhaXJzX000LnBsb3QNCmBgYA0KDQoNCiMjIyMgQWxsIFRpbWVwb2ludHMNCmBgYHtyfQ0KVG9sX1BhaXJzLnBsb3Q8LWdncGxvdChkYXRhPVRvbF9jb250cmFzdHMsIGFlcyh4PVJlc3BvbnNlLCB5PVNldCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJQYWlyd2lzZSBDb250cmFzdHMiKSsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGFuZ2xlPTQ1LCBoanVzdD0xKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3otMSwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSIiLCBmaWxsPSJFc3RpbWF0ZSIpO1RvbF9QYWlycy5wbG90DQpgYGANCg0KDQojIyMjIFNpZ25pZmljYW50IERpZmZlcmVuY2VzDQoNClN1YnNldHRpbmcgQ29udHJhc3RzIHRvIG9ubHkgaW5jbHVkZSBjb250cmFzdHMgd2l0aCBzaWduaWZpY2FudCBkaWZmZXJlbmNlcyBpbiBhdCBsZWFzdCBvbmUgb2YgdGhlIHRoZXJtYWwgdG9sZXJhbmNlIG1ldHJpY3MgKENobG9yb3BoeWxsIG9yIFN5bWJpb250IG9yIENvbG9yIHJldGVudGlvbikNCmBgYHtyfQ0KIyNSZW1vdmUgcm93cyB3aXRoIG5vbi1zaWduaWZpY2FudCBwLXZhbHVlcw0KVG9sX2NvbnRyYXN0c19zaWc8LXN1YnNldChUb2xfY29udHJhc3RzLCBwIDwgMC4wNSkNCg0KIyNLZWVwIFNldHMgd2hlcmUgYXQgbGVhc3Qgb25lIG1ldHJpYyBzaG93cyBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UNClRvbF9TZXRzX3NpZzwtZGF0YS5mcmFtZShTZXQ9Yyh1bmlxdWUoVG9sX2NvbnRyYXN0c19zaWckU2V0KSkpDQpUb2xfY29udHJhc3RzX3NpZ19TZXQ8LW1lcmdlKFRvbF9TZXRzX3NpZywgVG9sX2NvbnRyYXN0cywgYWxsLng9VFJVRSwgYWxsLnk9RkFMU0UpDQoNCmBgYA0KDQoNCmBgYHtyfQ0KVG9sX1BhaXJzX3NpZy5wbG90PC1nZ3Bsb3QoZGF0YT1Ub2xfY29udHJhc3RzX3NpZ19TZXQsIGFlcyh4PVJlc3BvbnNlLCB5PVNldCwgZmlsbD1Fc3RpbWF0ZSkpKw0KICBnZW9tX3RpbGUoKSsNCiAgZ2VvbV90ZXh0KGFlcyhsYWJlbD1TaWcpLCBzaXplPXNpZy5zeikrDQogIHNjYWxlX2ZpbGxfZ3JhZGllbnQyKGxvdz0iI0JBMUUwMkZGIiwgbWlkPSJ3aGl0ZSIsIGhpZ2g9IiMzQkEwRkRGRiIpKw0KICB0aGVtZV9idygpKw0KICBnZ3RpdGxlKCJTaWduaWZpY2FudCBQYWlyd2lzZSBDb250cmFzdHMiKSsNCiAgdGhlbWUoYXhpcy50ZXh0Lng9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGFuZ2xlPTQ1LCBoanVzdD0xKSwNCiAgICAgICAgYXhpcy50ZXh0Lnk9ZWxlbWVudF90ZXh0KHNpemU9YXhpcy50eHQuc3otMSwgY29sb3VyPSJibGFjayIpLA0KICAgICAgICBsZWdlbmQudGV4dD1lbGVtZW50X3RleHQoc2l6ZT1sZWcudHh0LnN6KSwNCiAgICAgICAgbGVnZW5kLnRpdGxlPWVsZW1lbnRfdGV4dChzaXplPWxlZy50aXRsZS5zeiksIA0KICAgICAgICBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKSsNCiAgbGFicyh4PSIiLCB5PSIiLCBmaWxsPSJFc3RpbWF0ZSIpO1RvbF9QYWlyc19zaWcucGxvdA0KYGBgDQoNCg0KIyMjIFByb3BvcnRpb24gb2YgQWdyZWVtZW50DQpBc3Nlc3NpbmcgdGhlIHByb3BvcnRpb24gb2YgYWdyZWVtZW50IGJldHdlZW4gbWV0aG9kcyBhcyB0aGUgcGFpcndpc2UgY29tcGFyaXNvbnMgd2hlcmUgdHdvIG1ldGhvZHMgYm90aCBmaW5kIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBvdXQgb2YgdGhlIHRvdGFsIHBhaXJ3aXNlIGNvbXBhcmlzb25zLiBDYWxjdWxhdGluZyB0aGUgcHJvcG9ydGlvbiBvZiBhZ3JlZW1lbnQgYmV0d2VlbiBDaGxvcm9waHlsbCBhbmQgQ29sb3IgRnVsbCBTZXQsIENobG9yb3BoeWxsIGFuZCBDb2xvciBUaW1lcG9pbnQsIFN5bWJpb250cyBhbmQgQ29sb3IgRnVsbCBTZXQsIFN5bWJpb250cyBhbmQgQ29sb3IgVGltZXBvaW50LCBhbmQgQ2hsb3JvcGh5bGwgYW5kIFN5bWJpb250cy4gQ29tcGFyaW5nIHRoZSBwcm9wb3J0aW9uIG9mIGFncmVlbWVudCBiZXR3ZWVuIG1ldGhvZHMgb2YgcXVhbnRpZnlpbmcgdGhlcm1hbCB0b2xlcmFuY2UuDQpgYGB7cn0NCm5hbWVzKFRvbF9jb250cmFzdHMpDQoNCiMjQ2hhbmdlIGxvbmcgdG8gc2hvcnQgZm9ybWF0DQpUb2xfY29udHJhc3RzLmFncmVlPC1Ub2xfY29udHJhc3RzICU+JSBwaXZvdF93aWRlcihuYW1lc19mcm9tPSJSZXNwb25zZSIsIHZhbHVlc19mcm9tPWMoInAiLCAiRXN0aW1hdGUiKSwgaWRfY29scz1jKCJUaW1lUCIsICJDb250cmFzdCIsICJTZXQiKSkNCg0KIyNDb252ZXJ0IHAgdmFsdWVzIHRvIGJpbmFyeQ0KIzA6IE5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgKHA+MC4wNSkgZGV0ZWN0ZWQgaW4gdGhhdCBwYWlyd2lzZSBjb250cmFzdA0KIzE6IFNpZ25pZmljYW50IGRpZmZlcmVuY2UgKHA8MC4wNSkgZGV0ZWN0ZWQgaW4gdGhhdCBwYWlyd2lzZSBjb250cmFzdA0KVG9sX2NvbnRyYXN0cy5hZ3JlZVssYyg0OjcpXTwtaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWVbLGMoNDo3KV08MC4wNSwgMSwgMCkNCg0KIyNDb252ZXJ0IGVzdGltYXRlcyB0byBHcmVhdGVyIG9yIExlc3MNCiNHcmVhdGVyOiBQb3NpdGl2ZSBlc3RpbWF0ZXMgaW5kaWNhdGUgQT5CIGluIHRoZSBDb250cmFzdA0KI0xlc3M6IE5lZ2F0aXZlIGVzdGltYXRlcyBpbmRpY2F0ZSBBPEIgaW4gdGhlIENvbnRyYXN0DQpUb2xfY29udHJhc3RzLmFncmVlWyxjKDg6MTEpXTwtaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWVbLGMoODoxMSldPDAsICJMZXNzIiwgIkdyZWF0ZXIiKQ0KDQojI0lkZW50aWZ5IGFncmVlbWVudA0KIzE6IEJvdGggbWV0cmljcyBpZGVudGlmaWVkIGEgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZSBpbiB0aGF0IHBhaXJ3aXNlIGNvbnRyYXN0IE9SIE5laXRoZXIgbWV0cmljIGlkZW50aWZpZWQgYSBzaWduaWZpY2FudCBkaWZmZXJlbmNlDQojMDogT25lIG1ldHJpY3MgaWRlbnRpZmllZCBhIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhhdCBwYWlyd2lzZSBjb250cmFzdA0KI0ZvciBlYWNoIG1hdGNoaW5nIGNhc2UgKDEpLCBjb25maXJtIG1hdGNoaW5nIEVzdGltYXRlcw0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRDaGwuU3ltPC1pZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT0xICYNClRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09VG9sX2NvbnRyYXN0cy5hZ3JlZSRwX1N5bWJpb250cyAmDQpUb2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NobG9yb3BoeWxsPT1Ub2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX1N5bWJpb250cywgMSwgDQppZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT0wICYgDQogICAgICAgICBUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHMsIDEsIDApKQ0KDQpUb2xfY29udHJhc3RzLmFncmVlJENobC5Db2xGPC1pZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT0xICYgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NobG9yb3BoeWxsPT1Ub2xfY29udHJhc3RzLmFncmVlJHBfQ29sb3JfRnVsbFNldCAmDQpUb2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NobG9yb3BoeWxsPT1Ub2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NvbG9yX0Z1bGxTZXQsIDEsIA0KaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09MCAmDQogICAgICAgICBUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9GdWxsU2V0LCAxLCAwKSkNCg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRDaGwuQ29sVFA8LWlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PTEgJiANClRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09VG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX1RQICYgICAgICAgICAgICAgICAgICAgICAgICAgIFRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ29sb3JfVFAsIDEsIA0KaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWUkcF9DaGxvcm9waHlsbD09MCAmDQogICAgICAgICBUb2xfY29udHJhc3RzLmFncmVlJHBfQ2hsb3JvcGh5bGw9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCwgMSwgMCkpDQoNClRvbF9jb250cmFzdHMuYWdyZWUkU3ltLkNvbEY8LWlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfU3ltYmlvbnRzPT0xICYNClRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9GdWxsU2V0ICYgVG9sX2NvbnRyYXN0cy5hZ3JlZSRFc3RpbWF0ZV9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ29sb3JfRnVsbFNldCwgMSwNCmlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfU3ltYmlvbnRzPT0wICYNCiAgICAgICAgIFRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9GdWxsU2V0LCAxLCAwKSkNCg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRTeW0uQ29sVFA8LWlmZWxzZShUb2xfY29udHJhc3RzLmFncmVlJHBfU3ltYmlvbnRzPT0xICYNClRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCAmIFRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfU3ltYmlvbnRzPT1Ub2xfY29udHJhc3RzLmFncmVlJEVzdGltYXRlX0NvbG9yX1RQLCAxLA0KaWZlbHNlKFRvbF9jb250cmFzdHMuYWdyZWUkcF9TeW1iaW9udHM9PTAgJg0KICAgICAgICAgVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX1N5bWJpb250cz09VG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX1RQLCAxLCAwKSkNCg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRDb2xGLkNvbFRQPC1pZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PTEgJg0KVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCAmIFRvbF9jb250cmFzdHMuYWdyZWUkRXN0aW1hdGVfQ29sb3JfRnVsbFNldD09VG9sX2NvbnRyYXN0cy5hZ3JlZSRFc3RpbWF0ZV9Db2xvcl9UUCwgMSwgDQppZmVsc2UoVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PTAgJg0KICAgICAgICAgVG9sX2NvbnRyYXN0cy5hZ3JlZSRwX0NvbG9yX0Z1bGxTZXQ9PVRvbF9jb250cmFzdHMuYWdyZWUkcF9Db2xvcl9UUCwgMSwgMCkpDQoNCiMjQ29udmVydCB0byBsb25nIHRvIGNhbGN1bGF0ZSBpbnN0YW5jZXMgb2YgYWdyZWVtZW50DQpUb2xfY29udHJhc3RzLmFncmVlLmxvbmc8LVRvbF9jb250cmFzdHMuYWdyZWUgJT4lIHBpdm90X2xvbmdlcihjb2xzPWMoIkNobC5TeW0iLCAiQ2hsLkNvbEYiLCAiQ2hsLkNvbFRQIiwgIlN5bS5Db2xGIiwgIlN5bS5Db2xUUCIsICJDb2xGLkNvbFRQIiksIG5hbWVzX3RvPSJDb21wYXJlIiwgdmFsdWVzX3RvPSJBZ3JlZSIpDQoNCiMjU3VtIENhc2VzIG9mIEFncmVlbWVudA0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW08LWFnZ3JlZ2F0ZShUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQWdyZWUsIGxpc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJENvbXBhcmUpLCBzdW0pDQpuYW1lcyhUb2xfY29udHJhc3RzLmFncmVlLnN1bSk8LWMoIkNvbXBhcmUiLCAiQWdyZWUiKQ0KDQojI1RvdGFsIFBhaXJ3aXNlIENvbXBhcmlzb25zDQpUb2xfY29udHJhc3RzLmFncmVlLnN1bSRUb3RhbDwtYWdncmVnYXRlKFRvbF9jb250cmFzdHMuYWdyZWUubG9uZyRBZ3JlZSwgbGlzdChUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQ29tcGFyZSksIGZ1bmN0aW9uKHgpIGxlbmd0aCh4KSlbLDJdDQpgYGANCg0KDQojIyMjIENvbXBhcmUgUHJvcG9ydGlvbiBBZ3JlZW1lbnQNCmBgYHtyfQ0KcHJvcC50ZXN0KFRvbF9jb250cmFzdHMuYWdyZWUuc3VtJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLnN1bSRUb3RhbCkNCg0KYGBgDQoNCk5vIHNpZ25pZmljYW50IGRpZmZlcmVuY2UgaW4gdGhlIHByb3BvcnRpb24gb2YgYWdyZWVtZW50IGluIGRldGVjdGluZyBwYWlyd2lzZSBkaWZmZXJlbmNlcyBpbiB0aGVybWFsIHRvbGVyYW5jZSBhY3Jvc3MgY29tcGFyaXNvbnMgb2YgdHJhZGl0aW9uYWwgYmxlYWNoaW5nIG9yIGNvbG9yIHNjb3JlIG1ldGhvZHMgKFBlYXJzb24ncyBjaGktc3F1YXJlZCB0ZXN0IHAtdmFsdWUgPSAwLjcyODEpDQoNCg0KIyMjIENvbXBhcmUgQWdyZWVtZW50IGFjcm9zcyBTZWFzb25zDQoNCmBgYHtyfQ0KIyNTdW0gQ2FzZXMgb2YgQWdyZWVtZW50IGJ5IENvbXBhcmlzb24gYW5kIFRpbWVwb2ludA0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW0udHA8LWFnZ3JlZ2F0ZShUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQWdyZWUsIGxpc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJFRpbWVQLCBUb2xfY29udHJhc3RzLmFncmVlLmxvbmckQ29tcGFyZSksIHN1bSkNCm5hbWVzKFRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwKTwtYygiVGltZVAiLCAiQ29tcGFyZSIsICJBZ3JlZSIpDQoNCiMjVG90YWwgUGFpcndpc2UgQ29tcGFyaXNvbnMNClRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwJFRvdGFsPC1hZ2dyZWdhdGUoVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJEFncmVlLCBsaXN0KFRvbF9jb250cmFzdHMuYWdyZWUubG9uZyRUaW1lUCwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5sb25nJENvbXBhcmUpLCBmdW5jdGlvbih4KSBsZW5ndGgoeCkpWywzXQ0KDQoNCmBgYA0KDQoNCiMjIyMgQ2hsIHZzIFN5bQ0KYGBge3J9DQojI1N1YnNldCBieSBDb21wYXJpc29uDQpUb2xfY29udHJhc3RzLmFncmVlLkNobC5TeW08LXN1YnNldChUb2xfY29udHJhc3RzLmFncmVlLnN1bS50cCwgQ29tcGFyZT09IkNobC5TeW0iKQ0KDQojI0NvbXBhcmUgUHJvcG9ydGlvbnMgYmV0d2VlbiBUaW1lcG9pbnRzDQpwcm9wLnRlc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuU3ltJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLkNobC5TeW0kVG90YWwpDQoNCmBgYA0KDQoNCiMjIyMgQ2hsIHZzIENvbG9yIEZ1bGwNCmBgYHtyfQ0KIyNTdWJzZXQgYnkgQ29tcGFyaXNvbg0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuQ29sRjwtc3Vic2V0KFRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwLCBDb21wYXJlPT0iQ2hsLkNvbEYiKQ0KDQojI0NvbXBhcmUgUHJvcG9ydGlvbnMgYmV0d2VlbiBUaW1lcG9pbnRzDQpwcm9wLnRlc3QoVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuQ29sRiRBZ3JlZSwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5DaGwuQ29sRiRUb3RhbCkNCg0KYGBgDQoNCiMjIyMgQ2hsIHZzIENvbG9yIFRpbWVwb2ludA0KYGBge3J9DQojI1N1YnNldCBieSBDb21wYXJpc29uDQpUb2xfY29udHJhc3RzLmFncmVlLkNobC5Db2xUUDwtc3Vic2V0KFRvbF9jb250cmFzdHMuYWdyZWUuc3VtLnRwLCBDb21wYXJlPT0iQ2hsLkNvbFRQIikNCg0KIyNDb21wYXJlIFByb3BvcnRpb25zIGJldHdlZW4gVGltZXBvaW50cw0KcHJvcC50ZXN0KFRvbF9jb250cmFzdHMuYWdyZWUuQ2hsLkNvbFRQJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLkNobC5Db2xUUCRUb3RhbCkNCg0KYGBgDQoNCg0KIyMjIyBTeW0gdnMgQ29sb3IgRnVsbA0KYGBge3J9DQojI1N1YnNldCBieSBDb21wYXJpc29uDQpUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xGPC1zdWJzZXQoVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW0udHAsIENvbXBhcmU9PSJTeW0uQ29sRiIpDQoNCiMjQ29tcGFyZSBQcm9wb3J0aW9ucyBiZXR3ZWVuIFRpbWVwb2ludHMNCnByb3AudGVzdChUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xGJEFncmVlLCBUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xGJFRvdGFsKQ0KDQpgYGANCg0KDQojIyMjIFN5bSB2cyBDb2xvciBUaW1lcG9pbnQNCmBgYHtyfQ0KIyNTdWJzZXQgYnkgQ29tcGFyaXNvbg0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5TeW0uQ29sVFA8LXN1YnNldChUb2xfY29udHJhc3RzLmFncmVlLnN1bS50cCwgQ29tcGFyZT09IlN5bS5Db2xUUCIpDQoNCiMjQ29tcGFyZSBQcm9wb3J0aW9ucyBiZXR3ZWVuIFRpbWVwb2ludHMNCnByb3AudGVzdChUb2xfY29udHJhc3RzLmFncmVlLlN5bS5Db2xUUCRBZ3JlZSwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5TeW0uQ29sVFAkVG90YWwpDQoNCmBgYA0KDQoNCiMjIyMgQ29sb3IgRnVsbCB2cyBDb2xvciBUaW1lcG9pbnQNCmBgYHtyfQ0KIyNTdWJzZXQgYnkgQ29tcGFyaXNvbg0KVG9sX2NvbnRyYXN0cy5hZ3JlZS5Db2xGLkNvbFRQPC1zdWJzZXQoVG9sX2NvbnRyYXN0cy5hZ3JlZS5zdW0udHAsIENvbXBhcmU9PSJDb2xGLkNvbFRQIikNCg0KIyNDb21wYXJlIFByb3BvcnRpb25zIGJldHdlZW4gVGltZXBvaW50cw0KcHJvcC50ZXN0KFRvbF9jb250cmFzdHMuYWdyZWUuQ29sRi5Db2xUUCRBZ3JlZSwgVG9sX2NvbnRyYXN0cy5hZ3JlZS5Db2xGLkNvbFRQJFRvdGFsKQ0KDQpgYGANCg0KDQojIEZpZ3VyZXMNCg0KIyMjIEZpZ3VyZSBTMiBUb2xlcmFuY2UgQWNyb3NzIE1ldHJpY3MNCg0KIyMjIyBVcGRhdGUgZm9yIFBhbmVsDQpgYGB7cn0NCg0KIyNUb3Agcm93DQpUb2xfQ2hsX1cyX1NHLnBsb3Q8LVRvbF9DaGxfVzJfU0cucGxvdCArIGdndGl0bGUoIlN1bW1lciAxIikgKyAgbGFicyh4PSIiKSsgDQogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0idG9wIiwgbGVnZW5kLmRpcmVjdGlvbj0iaG9yaXpvbnRhbCIsIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoc2l6ZSA9IHBsb3QudGl0bGUuc3osIGNvbG91cj0iYmxhY2siLCBoanVzdCA9IDAuNSkpDQoNClRvbF9DaGxfTTFfU0cucGxvdDwtVG9sX0NobF9NMV9TRy5wbG90ICsgZ2d0aXRsZSgiU3VtbWVyIDIiKSArICBsYWJzKHg9IiIsIHk9IiIpKyANCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJ0b3AiLCBsZWdlbmQuZGlyZWN0aW9uPSJob3Jpem9udGFsIiwgcGxvdC50aXRsZSA9IGVsZW1lbnRfdGV4dChzaXplID0gcGxvdC50aXRsZS5zeiwgY29sb3VyPSJibGFjayIsIGhqdXN0ID0gMC41KSkNCiAgDQpUb2xfQ2hsX000X1NHLnBsb3Q8LVRvbF9DaGxfTTRfU0cucGxvdCArIGdndGl0bGUoIldpbnRlciIpICsgIGxhYnMoeD0iIiwgeT0iIikrIA0KICB0aGVtZShsZWdlbmQucG9zaXRpb249InRvcCIsIGxlZ2VuZC5kaXJlY3Rpb249Imhvcml6b250YWwiLCBwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSBwbG90LnRpdGxlLnN6LCBjb2xvdXI9ImJsYWNrIiwgaGp1c3QgPSAwLjUpKQ0KICANCiMjQm90dG9tIHJvdw0KVG9sX1N5bV9XMl9TRy5wbG90PC1Ub2xfU3ltX1cyX1NHLnBsb3QrbGFicyh4PSJTaXRlIGFuZCBHZW5vdHlwZSIpKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KDQpUb2xfU3ltX00xX1NHLnBsb3Q8LVRvbF9TeW1fTTFfU0cucGxvdCtsYWJzKHg9IlNpdGUgYW5kIEdlbm90eXBlIiwgeT0iIikrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNClRvbF9TeW1fTTRfU0cucGxvdDwtVG9sX1N5bV9NNF9TRy5wbG90K2xhYnMoeD0iU2l0ZSBhbmQgR2Vub3R5cGUiLCB5PSIiKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KDQojI0NvbG9yIHNjb3Jlcw0KVG9sX1Njb3JlRl9XMl9TRy5wbG90PC1Ub2xfU2NvcmVGX1cyX1NHLnBsb3QrbGFicyh4PSIiKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KVG9sX1Njb3JlRl9NMV9TRy5wbG90PC1Ub2xfU2NvcmVGX00xX1NHLnBsb3QrbGFicyh4PSIiLCB5PSIiKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KVG9sX1Njb3JlRl9NNF9TRy5wbG90PC1Ub2xfU2NvcmVGX000X1NHLnBsb3QrbGFicyh4PSIiLCB5PSIiKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KDQpUb2xfU2NvcmVUUF9XMl9TRy5wbG90PC1Ub2xfU2NvcmVUUF9XMl9TRy5wbG90K2xhYnMoeD0iIikrIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpDQoNClRvbF9TY29yZVRQX00xX1NHLnBsb3Q8LVRvbF9TY29yZVRQX00xX1NHLnBsb3QrbGFicyh4PSIiLCB5PSIiKSsgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikNCg0KVG9sX1Njb3JlVFBfTTRfU0cucGxvdDwtVG9sX1Njb3JlVFBfTTRfU0cucGxvdCtsYWJzKHg9IiIsIHk9IiIpKyB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKQ0KDQpgYGANCg0KDQojIyMjIEZpZ3VyZSBTMg0KYGBge3J9DQojI0NyZWF0ZSBQYW5lbA0KVG9sZXJhbmNlX2ZpZzwtcGxvdF9ncmlkKFRvbF9DaGxfVzJfU0cucGxvdCwgVG9sX0NobF9NMV9TRy5wbG90LCBUb2xfQ2hsX000X1NHLnBsb3QsDQogICAgICAgICAgICAgICAgICBUb2xfU2NvcmVGX1cyX1NHLnBsb3QsIFRvbF9TY29yZUZfTTFfU0cucGxvdCwgVG9sX1Njb3JlRl9NNF9TRy5wbG90LA0KICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfU0cucGxvdCwgVG9sX1Njb3JlVFBfTTFfU0cucGxvdCwgVG9sX1Njb3JlVFBfTTRfU0cucGxvdCwNCiAgICAgICAgICAgICAgICAgIFRvbF9TeW1fVzJfU0cucGxvdCwgVG9sX1N5bV9NMV9TRy5wbG90LCBUb2xfU3ltX000X1NHLnBsb3QsDQogICAgICAgICAgICAgICAgICAgICAgICBucm93PTQsIG5jb2w9MywgYnlyb3c9VFJVRSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbF93aWR0aHM9MSwNCiAgICAgICAgICAgICAgICAgICAgICAgIHJlbF9oZWlnaHRzPWMoMSwgMC44NSwgMC44NSwgMC44NSksIA0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoImEiLCAiYiIsICJjIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZCIsICJlIiwgImYiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJnIiwgImgiLCAiaSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImoiLCAiayIsICJsIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxfc2l6ZT1wYW5lbC5sYWIuc3osIA0KICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxfZm9udGZhY2UgPSAiYm9sZCIpDQoNCiMjU2F2ZSBGaWd1cmUNCmdnc2F2ZShmaWxlbmFtZT0iRmlndXJlcy9GaWd1cmVTMl9Ub2xlcmFuY2VfQWNyb3NzX01ldHJpY3MucG5nIiwgcGxvdD1Ub2xlcmFuY2VfZmlnLCBkcGk9MzAwLCB3aWR0aD0xNCwgaGVpZ2h0PTIwLCB1bml0cz0iaW4iKQ0KDQpgYGANCg0KDQojIyMgRmlndXJlIDQgQ29udHJhc3RzIEhlYXRtYXANCmBgYHtyfQ0KIyNTYXZlIEZpZ3VyZQ0KZ2dzYXZlKGZpbGVuYW1lPSJGaWd1cmVzL0ZpZ3VyZTRfVG9sZXJhbmNlX0hlYXRtYXAucG5nIiwgcGxvdD1Ub2xfUGFpcnMucGxvdCwgZHBpPTMwMCwgd2lkdGg9OCwgaGVpZ2h0PTEyLCB1bml0cz0iaW4iKQ0KDQpgYGANCg0KDQojIFRhYmxlcw0KDQojIyMgVGFibGUgUzIgTGluZWFyIE1vZGVsIFJlc3VsdHMNCmBgYHtyfQ0KIyNDb21iaW5lIFJlc3VsdHMgVGFibGVzDQpUYWJsZVMyX1RvbC5sbS5yZXM8LXJiaW5kKFRvbF9DaGxfVzJfbG0ucmVzLCBUb2xfQ2hsX00xX2xtLnJlcywgVG9sX0NobF9NNF9sbS5yZXMsDQogICAgICAgICAgICAgICAgICAgICAgICBUb2xfU3ltX1cyX2xtLnJlcywgVG9sX1N5bV9NMV9sbS5yZXMsIFRvbF9TeW1fTTRfbG0ucmVzLA0KICAgICAgICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlRl9XMl9sbS5yZXMsIFRvbF9TY29yZUZfTTFfbG0ucmVzLCBUb2xfU2NvcmVGX000X2xtLnJlcywNCiAgICAgICAgICAgICAgICAgICAgVG9sX1Njb3JlVFBfVzJfbG0ucmVzLCBUb2xfU2NvcmVUUF9NMV9sbS5yZXMsIFRvbF9TY29yZVRQX000X2xtLnJlcykNCg0KIyNBZGQgYSBTZWFzb24gVmFyaWFibGUNClRhYmxlUzJfVG9sLmxtLnJlcyRTZWFzb248LWlmZWxzZShUYWJsZVMyX1RvbC5sbS5yZXMkVGltZVA9PSJXMiIsICJTdW1tZXIxIiwgaWZlbHNlKFRhYmxlUzJfVG9sLmxtLnJlcyRUaW1lUD09Ik0xIiwgIlN1bW1lcjIiLCBpZmVsc2UoVGFibGVTMl9Ub2wubG0ucmVzJFRpbWVQPT0iTTQiLCAiV2ludGVyIiAsIE5BKSkpDQoNCiMjT3JnYW5pemUNCm5hbWVzKFRhYmxlUzJfVG9sLmxtLnJlcykNClRhYmxlUzJfVG9sLmxtLnJlczwtVGFibGVTMl9Ub2wubG0ucmVzWyxjKCJUaW1lUCIsICJTZWFzb24iLCAiUmVzcG9uc2UiLCAiUHJlZGljdG9yIiwgIkRGIiwgIlN1bS5TcSIsICJNZWFuLlNxIiwgIkYudmFsdWUiLCAicC52YWx1ZSIsICJFdGFTcSIpXQ0KDQojUm91bmQgdG8gNCBkaWdpdHMNClRhYmxlUzJfVG9sLmxtLnJlcyRTdW0uU3E8LXJvdW5kKFRhYmxlUzJfVG9sLmxtLnJlcyRTdW0uU3EsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkTWVhbi5TcTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJE1lYW4uU3EsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkRi52YWx1ZTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJEYudmFsdWUsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkcC52YWx1ZTwtcm91bmQoVGFibGVTMl9Ub2wubG0ucmVzJHAudmFsdWUsIDQpDQpUYWJsZVMyX1RvbC5sbS5yZXMkRXRhU3E8LXJvdW5kKFRhYmxlUzJfVG9sLmxtLnJlcyRFdGFTcSwgNCkNCg0KIyNXcml0ZSBPdXQgVGFibGUNCndyaXRlLmNzdihUYWJsZVMyX1RvbC5sbS5yZXMsICJUYWJsZXMvVGFibGVTMl9Ub2xlcmFuY2VfTE1fUmVzdWx0cy5jc3YiLCByb3cubmFtZXM9RkFMU0UpDQoNCmBgYA0KDQoNCiMjIyBUYWJsZSBTMyBQYWlyd2lzZSBDb21wYXJpc29uIFJlc3VsdHMNCmBgYHtyfQ0KIyNQYWlyd2lzZSBSZXN1bHRzIFRhYmxlDQpUYWJsZVMzX1RvbC5wYWlyd2lzZTwtVG9sX2NvbnRyYXN0cw0KDQojI0FkZCBhIFNlYXNvbiBWYXJpYWJsZQ0KVGFibGVTM19Ub2wucGFpcndpc2UkU2Vhc29uPC1pZmVsc2UoVGFibGVTM19Ub2wucGFpcndpc2UkVGltZVA9PSJXMiIsICJTdW1tZXIxIiwgaWZlbHNlKFRhYmxlUzNfVG9sLnBhaXJ3aXNlJFRpbWVQPT0iTTEiLCAiU3VtbWVyMiIsIGlmZWxzZShUYWJsZVMzX1RvbC5wYWlyd2lzZSRUaW1lUD09Ik00IiwgIldpbnRlciIgLCBOQSkpKQ0KDQojI1JlLW9yZGVyIGJ5IFNlYXNvbmFsIFRpbWVwb2ludA0KVGFibGVTM19Ub2wucGFpcndpc2U8LSBUYWJsZVMzX1RvbC5wYWlyd2lzZSAlPiUgYXJyYW5nZShhcy5udW1lcmljKFRpbWVQKSkNCg0KIyNPcmdhbml6ZQ0KbmFtZXMoVGFibGVTM19Ub2wucGFpcndpc2UpDQpUYWJsZVMzX1RvbC5wYWlyd2lzZTwtVGFibGVTM19Ub2wucGFpcndpc2VbLGMoIlRpbWVQIiwgIlNlYXNvbiIsICJSZXNwb25zZSIsICJDb250cmFzdCIsICJFc3RpbWF0ZSIsICJTRSIsICJkZiIsICJ0LnJhdGlvIiwgInAiKV0NClRhYmxlUzNfVG9sLnBhaXJ3aXNlPC1UYWJsZVMzX1RvbC5wYWlyd2lzZSAlPiUgZHBseXI6OnJlbmFtZSggREYgPSBkZikgJT4lIGRwbHlyOjpyZW5hbWUoIHAudmFsdWUgPSBwKQ0KDQojUm91bmQgdG8gNCBkaWdpdHMNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJEVzdGltYXRlPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRFc3RpbWF0ZSwgNCkNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJFNFPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRTRSwgNCkNClRhYmxlUzNfVG9sLnBhaXJ3aXNlJHQucmF0aW88LXJvdW5kKFRhYmxlUzNfVG9sLnBhaXJ3aXNlJHQucmF0aW8sIDQpDQpUYWJsZVMzX1RvbC5wYWlyd2lzZSRwLnZhbHVlPC1yb3VuZChUYWJsZVMzX1RvbC5wYWlyd2lzZSRwLnZhbHVlLCA0KQ0KDQojI1dyaXRlIE91dCBUYWJsZQ0Kd3JpdGUuY3N2KFRhYmxlUzNfVG9sLnBhaXJ3aXNlLCAiVGFibGVzL1RhYmxlUzNfVG9sZXJhbmNlX1BhaXJ3aXNlX1Jlc3VsdHMuY3N2Iiwgcm93Lm5hbWVzPUZBTFNFKQ0KYGBgDQoNCg==